001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.extensions;
028
029
030
031 import org.opends.messages.Message;
032 import org.opends.server.admin.std.server.CancelExtendedOperationHandlerCfg;
033 import org.opends.server.api.ClientConnection;
034 import org.opends.server.api.ExtendedOperationHandler;
035 import org.opends.server.config.ConfigException;
036 import org.opends.server.core.DirectoryServer;
037 import org.opends.server.core.ExtendedOperation;
038 import org.opends.server.loggers.debug.DebugTracer;
039 import org.opends.server.protocols.asn1.ASN1Sequence;
040 import org.opends.server.types.ByteString;
041 import org.opends.server.types.CancelRequest;
042 import org.opends.server.types.CancelResult;
043 import org.opends.server.types.DebugLogLevel;
044 import org.opends.server.types.InitializationException;
045 import org.opends.server.types.ResultCode;
046
047 import static org.opends.messages.ExtensionMessages.*;
048 import static org.opends.server.loggers.debug.DebugLogger.*;
049 import static org.opends.server.util.ServerConstants.*;
050 import static org.opends.server.util.StaticUtils.*;
051
052
053
054 /**
055 * This class implements the LDAP cancel extended operation defined in RFC 3909.
056 * It is similar to the LDAP abandon operation, with the exception that it
057 * requires a response for both the operation that is cancelled and the cancel
058 * request (whereas an abandon request never has a response, and if it is
059 * successful the abandoned operation won't get one either).
060 */
061 public class CancelExtendedOperation
062 extends ExtendedOperationHandler<CancelExtendedOperationHandlerCfg>
063 {
064 /**
065 * The tracer object for the debug logger.
066 */
067 private static final DebugTracer TRACER = getTracer();
068
069
070
071 /**
072 * Create an instance of this cancel extended operation. All initialization
073 * should be performed in the <CODE>initializeExtendedOperationHandler</CODE>
074 * method.
075 */
076 public CancelExtendedOperation()
077 {
078 super();
079 }
080
081
082 /**
083 * Initializes this extended operation handler based on the information in the
084 * provided configuration entry. It should also register itself with the
085 * Directory Server for the particular kinds of extended operations that it
086 * will process.
087 *
088 * @param config The configuration that contains the information
089 * to use to initialize this extended operation handler.
090 *
091 * @throws ConfigException If an unrecoverable problem arises in the
092 * process of performing the initialization.
093 *
094 * @throws InitializationException If a problem occurs during initialization
095 * that is not related to the server
096 * configuration.
097 */
098 public void initializeExtendedOperationHandler(
099 CancelExtendedOperationHandlerCfg config)
100 throws ConfigException, InitializationException
101 {
102 // No special configuration is required.
103
104 DirectoryServer.registerSupportedExtension(OID_CANCEL_REQUEST, this);
105
106 registerControlsAndFeatures();
107 }
108
109
110
111 /**
112 * Performs any finalization that may be necessary for this extended
113 * operation handler. By default, no finalization is performed.
114 */
115 public void finalizeExtendedOperationHandler()
116 {
117 DirectoryServer.deregisterSupportedExtension(OID_CANCEL_REQUEST);
118
119 deregisterControlsAndFeatures();
120 }
121
122
123
124 /**
125 * Processes the provided extended operation.
126 *
127 * @param operation The extended operation to be processed.
128 */
129 public void processExtendedOperation(ExtendedOperation operation)
130 {
131 // The value of the request must be a sequence containing an integer element
132 // that holds the message ID of the operation to cancel. If there is no
133 // value or it cannot be decoded, then fail.
134 int idToCancel;
135 ByteString requestValue = operation.getRequestValue();
136 if (requestValue == null)
137 {
138 operation.setResultCode(ResultCode.PROTOCOL_ERROR);
139
140 operation.appendErrorMessage(ERR_EXTOP_CANCEL_NO_REQUEST_VALUE.get());
141 return;
142 }
143 else
144 {
145 try
146 {
147 ASN1Sequence valueSequence =
148 ASN1Sequence.decodeAsSequence(requestValue.value());
149 idToCancel =
150 valueSequence.elements().get(0).decodeAsInteger().intValue();
151 }
152 catch (Exception e)
153 {
154 if (debugEnabled())
155 {
156 TRACER.debugCaught(DebugLogLevel.ERROR, e);
157 }
158
159 operation.setResultCode(ResultCode.PROTOCOL_ERROR);
160
161 Message message = ERR_EXTOP_CANCEL_CANNOT_DECODE_REQUEST_VALUE.get(
162 getExceptionMessage(e));
163 operation.appendErrorMessage(message);
164
165 return;
166 }
167 }
168
169
170 // Create the cancel request for the target operation.
171 Message cancelReason =
172 INFO_EXTOP_CANCEL_REASON.get(operation.getMessageID());
173 CancelRequest cancelRequest = new CancelRequest(true, cancelReason);
174
175
176 // Get the client connection and attempt the cancel.
177 ClientConnection clientConnection = operation.getClientConnection();
178 CancelResult cancelResult = clientConnection.cancelOperation(idToCancel,
179 cancelRequest);
180
181
182 // Update the result of the extended operation and return.
183 operation.setResultCode(cancelResult.getResultCode());
184 operation.appendErrorMessage(cancelResult.getResponseMessage());
185 }
186 }
187