From 16781afd94b0ad1014b8394f524ffcc5bd89255b Mon Sep 17 00:00:00 2001
From: jarnou <jarnou@localhost>
Date: Tue, 17 Jul 2007 13:35:12 +0000
Subject: [PATCH] This fix is the refactoring of the extended operation (issue 1189).
---
opends/src/server/org/opends/server/core/ExtendedOperation.java | 697 ++--------------------------------------------------------
1 files changed, 25 insertions(+), 672 deletions(-)
diff --git a/opends/src/server/org/opends/server/core/ExtendedOperation.java b/opends/src/server/org/opends/server/core/ExtendedOperation.java
index a683fc1..c588942 100644
--- a/opends/src/server/org/opends/server/core/ExtendedOperation.java
+++ b/opends/src/server/org/opends/server/core/ExtendedOperation.java
@@ -26,137 +26,26 @@
*/
package org.opends.server.core;
-
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.opends.server.api.ClientConnection;
-import org.opends.server.api.ExtendedOperationHandler;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.DN;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.operation.PostOperationExtendedOperation;
-import org.opends.server.types.operation.PostResponseExtendedOperation;
-import org.opends.server.types.operation.PreOperationExtendedOperation;
-import org.opends.server.types.operation.PreParseExtendedOperation;
-
-import static org.opends.server.core.CoreConstants.*;
-import static org.opends.server.loggers.AccessLogger.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-
-import org.opends.server.loggers.debug.DebugLogger;
-import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.DebugLogLevel;
-import static org.opends.server.messages.CoreMessages.*;
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.util.ServerConstants.*;
+import org.opends.server.types.Operation;
/**
- * This class defines an extended operation, which can perform virtually any
+ * This interface defines an extended operation, which can perform virtually any
* kind of task.
*/
-public class ExtendedOperation
- extends AbstractOperation
- implements PreParseExtendedOperation, PreOperationExtendedOperation,
- PostOperationExtendedOperation, PostResponseExtendedOperation
+public interface ExtendedOperation
+ extends Operation
{
/**
- * The tracer object for the debug logger.
- */
- private static final DebugTracer TRACER = DebugLogger.getTracer();
-
- // The value for the request associated with this extended operation.
- private ASN1OctetString requestValue;
-
- // The value for the response associated with this extended operation.
- private ASN1OctetString responseValue;
-
- // Indicates whether a response has yet been sent for this operation.
- private boolean responseSent;
-
- // The cancel request that has been issued for this extended operation.
- private CancelRequest cancelRequest;
-
- // The set of response controls for this extended operation.
- private List<Control> responseControls;
-
- // The OID for the request associated with this extended operation.
- private String requestOID;
-
- // The OID for the response associated with this extended operation.
- private String responseOID;
-
-
-
- /**
- * Creates a new extended operation with the provided information.
+ * Retrieves the OID for the request associated with this extended
+ * operation.
*
- * @param clientConnection The client connection with which this operation
- * is associated.
- * @param operationID The operation ID for this operation.
- * @param messageID The message ID of the request with which this
- * operation is associated.
- * @param requestControls The set of controls included in the request.
- * @param requestOID The OID for the request associated with this
- * extended operation.
- * @param requestValue The value for the request associated with this
- * extended operation.
+ * @return The OID for the request associated with this extended
+ * operation.
*/
- public ExtendedOperation(ClientConnection clientConnection, long operationID,
- int messageID, List<Control> requestControls,
- String requestOID, ASN1OctetString requestValue)
- {
- super(clientConnection, operationID, messageID, requestControls);
-
-
- this.requestOID = requestOID;
- this.requestValue = requestValue;
-
- responseOID = null;
- responseValue = null;
- responseControls = new ArrayList<Control>();
- cancelRequest = null;
- responseSent = false;
- }
-
-
-
- /**
- * Retrieves the OID for the request associated with this extended operation.
- *
- * @return The OID for the request associated with this extended operation.
- */
- public final String getRequestOID()
- {
- return requestOID;
- }
-
-
-
- /**
- * Specifies the OID for the request associated with this extended operation.
- * This should only be called by pre-parse plugins.
- *
- * @param requestOID The OID for the request associated with this extended
- * operation.
- */
- public final void setRequestOID(String requestOID)
- {
- this.requestOID = requestOID;
- }
+ public String getRequestOID();
@@ -164,498 +53,48 @@
* Retrieves the value for the request associated with this extended
* operation.
*
- * @return The value for the request associated with this extended operation.
+ * @return The value for the request associated with this extended
+ * operation.
*/
- public final ASN1OctetString getRequestValue()
- {
- return requestValue;
- }
+ public ASN1OctetString getRequestValue();
/**
- * Specifies the value for the request associated with this extended
- * operation. This should only be called by pre-parse plugins.
- *
- * @param requestValue The value for the request associated with this
- * extended operation.
- */
- public final void setRequestValue(ASN1OctetString requestValue)
- {
- this.requestValue = requestValue;
- }
-
-
-
- /**
- * Retrieves the OID to include in the response to the client. This should
- * not be called by pre-parse or pre-operation plugins.
+ * Retrieves the OID to include in the response to the client.
*
* @return The OID to include in the response to the client.
*/
- public final String getResponseOID()
- {
- return responseOID;
- }
+ public String getResponseOID();
/**
- * Specifies the OID to include in the response to the client. This should
- * not be called by post-response plugins.
+ * Specifies the OID to include in the response to the client.
*
- * @param responseOID The OID to include in the response to the client.
+ * @param responseOID The OID to include in the response to the
+ * client.
*/
- public final void setResponseOID(String responseOID)
- {
- this.responseOID = responseOID;
- }
+ public void setResponseOID(String responseOID);
/**
- * Retrieves the value to include in the response to the client. This should
- * not be called by pre-parse or pre-operation plugins.
+ * Retrieves the value to include in the response to the client.
*
* @return The value to include in the response to the client.
*/
- public final ASN1OctetString getResponseValue()
- {
- return responseValue;
- }
+ public ASN1OctetString getResponseValue();
/**
- * Specifies the value to include in the response to the client. This should
- * not be called by post-response plugins.
+ * Specifies the value to include in the response to the client.
*
- * @param responseValue The value to include in the response to the client.
+ * @param responseValue The value to include in the response to
+ * the client.
*/
- public final void setResponseValue(ASN1OctetString responseValue)
- {
- this.responseValue = responseValue;
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final OperationType getOperationType()
- {
- // Note that no debugging will be done in this method because it is a likely
- // candidate for being called by the logging subsystem.
-
- return OperationType.EXTENDED;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final void disconnectClient(DisconnectReason disconnectReason,
- boolean sendNotification, String message,
- int messageID)
- {
- // Before calling clientConnection.disconnect, we need to mark this
- // operation as cancelled so that the attempt to cancel it later won't cause
- // an unnecessary delay.
- setCancelResult(CancelResult.CANCELED);
-
- clientConnection.disconnect(disconnectReason, sendNotification, message,
- messageID);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final String[][] getRequestLogElements()
- {
- // Note that no debugging will be done in this method because it is a likely
- // candidate for being called by the logging subsystem.
-
- return new String[][]
- {
- new String[] { LOG_ELEMENT_EXTENDED_REQUEST_OID, requestOID }
- };
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final String[][] getResponseLogElements()
- {
- // Note that no debugging will be done in this method because it is a likely
- // candidate for being called by the logging subsystem.
-
- String resultCode = String.valueOf(getResultCode().getIntValue());
-
- String errorMessage;
- StringBuilder errorMessageBuffer = getErrorMessage();
- if (errorMessageBuffer == null)
- {
- errorMessage = null;
- }
- else
- {
- errorMessage = errorMessageBuffer.toString();
- }
-
- String matchedDNStr;
- DN matchedDN = getMatchedDN();
- if (matchedDN == null)
- {
- matchedDNStr = null;
- }
- else
- {
- matchedDNStr = matchedDN.toString();
- }
-
- String referrals;
- List<String> referralURLs = getReferralURLs();
- if ((referralURLs == null) || referralURLs.isEmpty())
- {
- referrals = null;
- }
- else
- {
- StringBuilder buffer = new StringBuilder();
- Iterator<String> iterator = referralURLs.iterator();
- buffer.append(iterator.next());
-
- while (iterator.hasNext())
- {
- buffer.append(", ");
- buffer.append(iterator.next());
- }
-
- referrals = buffer.toString();
- }
-
- String processingTime =
- String.valueOf(getProcessingTime());
-
- return new String[][]
- {
- new String[] { LOG_ELEMENT_RESULT_CODE, resultCode },
- new String[] { LOG_ELEMENT_ERROR_MESSAGE, errorMessage },
- new String[] { LOG_ELEMENT_MATCHED_DN, matchedDNStr },
- new String[] { LOG_ELEMENT_REFERRAL_URLS, referrals },
- new String[] { LOG_ELEMENT_EXTENDED_RESPONSE_OID, responseOID },
- new String[] { LOG_ELEMENT_PROCESSING_TIME, processingTime }
- };
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final List<Control> getResponseControls()
- {
- return responseControls;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final void addResponseControl(Control control)
- {
- responseControls.add(control);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final void removeResponseControl(Control control)
- {
- responseControls.remove(control);
- }
-
-
-
- /**
- * Performs the work of actually processing this operation. This
- * should include all processing for the operation, including
- * invoking plugins, logging messages, performing access control,
- * managing synchronization, and any other work that might need to
- * be done in the course of processing.
- */
- public final void run()
- {
- setResultCode(ResultCode.UNDEFINED);
-
-
- // Get the plugin config manager that will be used for invoking plugins.
- PluginConfigManager pluginConfigManager =
- DirectoryServer.getPluginConfigManager();
- boolean skipPostOperation = false;
-
-
- // Start the processing timer.
- setProcessingStartTime();
-
-
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
- requestOID.equals(OID_START_TLS_REQUEST)))
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- return;
- }
- }
-
-
- // Create a labeled block of code that we can break out of if a problem is
- // detected.
-extendedProcessing:
- {
- // Invoke the pre-parse extended plugins.
- PreParsePluginResult preParseResult =
- pluginConfigManager.invokePreParseExtendedPlugins(this);
- if (preParseResult.connectionTerminated())
- {
- // There's no point in continuing with anything. Log the request and
- // result and return.
- setResultCode(ResultCode.CANCELED);
-
- int msgID = MSGID_CANCELED_BY_PREPARSE_DISCONNECT;
- appendErrorMessage(getMessage(msgID));
-
- setProcessingStopTime();
-
- logExtendedRequest(this);
- logExtendedResponse(this);
- pluginConfigManager.invokePostResponseExtendedPlugins(this);
- return;
- }
- else if (preParseResult.sendResponseImmediately())
- {
- skipPostOperation = true;
- logExtendedRequest(this);
- break extendedProcessing;
- }
- else if (preParseResult.skipCoreProcessing())
- {
- skipPostOperation = false;
- break extendedProcessing;
- }
-
-
- // Log the extended request message.
- logExtendedRequest(this);
-
-
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
- requestOID.equals(OID_START_TLS_REQUEST)))
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- pluginConfigManager.invokePostResponseExtendedPlugins(this);
- return;
- }
- }
-
-
- // Get the extended operation handler for the request OID. If there is
- // none, then fail.
- ExtendedOperationHandler handler =
- DirectoryServer.getExtendedOperationHandler(requestOID);
- if (handler == null)
- {
- setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
- appendErrorMessage(getMessage(MSGID_EXTENDED_NO_HANDLER,
- String.valueOf(requestOID)));
- break extendedProcessing;
- }
-
-
- // Look at the controls included in the request and ensure that all
- // critical controls are supported by the handler.
- List<Control> requestControls = getRequestControls();
- if ((requestControls != null) && (! requestControls.isEmpty()))
- {
- for (Control c : requestControls)
- {
- if (! c.isCritical())
- {
- // The control isn't critical, so we don't care if it's supported
- // or not.
- }
- else if (! handler.supportsControl(c.getOID()))
- {
- setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
-
- int msgID = MSGID_EXTENDED_UNSUPPORTED_CRITICAL_CONTROL;
- appendErrorMessage(getMessage(msgID, String.valueOf(requestOID),
- c.getOID()));
-
- break extendedProcessing;
- }
- }
- }
-
-
- // Check to see if the client has permission to perform the
- // extended operation.
-
- // FIXME: for now assume that this will check all permission
- // pertinent to the operation. This includes proxy authorization
- // and any other controls specified.
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isAllowed(this) == false) {
- setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_EXTENDED_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- appendErrorMessage(getMessage(msgID, String.valueOf(requestOID)));
-
- skipPostOperation = true;
- break extendedProcessing;
- }
-
- // Invoke the pre-operation extended plugins.
- PreOperationPluginResult preOpResult =
- pluginConfigManager.invokePreOperationExtendedPlugins(this);
- if (preOpResult.connectionTerminated())
- {
- // There's no point in continuing with anything. Log the result
- // and return.
- setResultCode(ResultCode.CANCELED);
-
- int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
- appendErrorMessage(getMessage(msgID));
-
- setProcessingStopTime();
-
- logExtendedResponse(this);
- pluginConfigManager.invokePostResponseExtendedPlugins(this);
- return;
- }
- else if (preOpResult.sendResponseImmediately())
- {
- skipPostOperation = true;
- break extendedProcessing;
- }
- else if (preOpResult.skipCoreProcessing())
- {
- skipPostOperation = false;
- break extendedProcessing;
- }
-
-
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
- requestOID.equals(OID_START_TLS_REQUEST)))
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- pluginConfigManager.invokePostResponseExtendedPlugins(this);
- return;
- }
- }
-
-
- // Actually perform the processing for this operation.
- handler.processExtendedOperation(this);
- }
-
-
- // Indicate that it is now too late to attempt to cancel the operation.
- setCancelResult(CancelResult.TOO_LATE);
-
-
- // Invoke the post-operation extended plugins.
- if (! skipPostOperation)
- {
- PostOperationPluginResult postOpResult =
- pluginConfigManager.invokePostOperationExtendedPlugins(this);
- if (postOpResult.connectionTerminated())
- {
- // There's no point in continuing with anything. Log the result and
- // return.
- setResultCode(ResultCode.CANCELED);
-
- int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
- appendErrorMessage(getMessage(msgID));
-
- setProcessingStopTime();
-
- logExtendedResponse(this);
- pluginConfigManager.invokePostResponseExtendedPlugins(this);
- return;
- }
- }
-
-
- // Stop the processing timer.
- setProcessingStopTime();
-
-
- // Send the response to the client, if it has not already been sent.
- if (! responseSent)
- {
- responseSent = true;
- clientConnection.sendResponse(this);
- }
-
-
- // Log the extended response.
- logExtendedResponse(this);
-
-
-
- // Invoke the post-response extended plugins.
- pluginConfigManager.invokePostResponseExtendedPlugins(this);
- }
-
-
-
- /**
- * Sends an extended response to the client if none has already been sent.
- * Note that extended operation handlers are strongly discouraged from using
- * this method when it is not necessary because its use will prevent the
- * response from being sent after post-operation plugin processing, which may
- * impact the result that should be included. Nevertheless, it may be needed
- * in some special cases in which the response must be sent before the
- * extended operation handler completes its processing (e.g., the StartTLS
- * operation in which the response must be sent in the clear before actually
- * enabling TLS protection).
- */
- public final void sendExtendedResponse()
- {
- if (! responseSent)
- {
- responseSent = true;
- clientConnection.sendResponse(this);
- }
- }
-
-
+ public void setResponseValue(ASN1OctetString responseValue);
/**
* Indicates that the response for this extended operation has been sent from
@@ -663,92 +102,6 @@
* extended operation for the case in which it needs to send a response in the
* clear after TLS negotiation has already started on the connection.
*/
- public final void setResponseSent()
- {
- this.responseSent = true;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final CancelResult cancel(CancelRequest cancelRequest)
- {
- this.cancelRequest = cancelRequest;
-
- CancelResult cancelResult = getCancelResult();
- long stopWaitingTime = System.currentTimeMillis() + 5000;
- while ((cancelResult == null) &&
- (System.currentTimeMillis() < stopWaitingTime))
- {
- try
- {
- Thread.sleep(50);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- }
-
- cancelResult = getCancelResult();
- }
-
- if (cancelResult == null)
- {
- // This can happen in some rare cases (e.g., if a client disconnects and
- // there is still a lot of data to send to that client), and in this case
- // we'll prevent the cancel thread from blocking for a long period of
- // time.
- cancelResult = CancelResult.CANNOT_CANCEL;
- }
-
- return cancelResult;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final CancelRequest getCancelRequest()
- {
- return cancelRequest;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public boolean setCancelRequest(CancelRequest cancelRequest)
- {
- this.cancelRequest = cancelRequest;
- return true;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final void toString(StringBuilder buffer)
- {
- buffer.append("ExtendedOperation(connID=");
- buffer.append(clientConnection.getConnectionID());
- buffer.append(", opID=");
- buffer.append(operationID);
- buffer.append(", oid=");
- buffer.append(requestOID);
- buffer.append(")");
- }
-
+ public void setResponseSent();
}
--
Gitblit v1.10.0