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 legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2011-2015 ForgeRock AS.
026 */
027package org.opends.server.types;
028
029import java.util.List;
030import java.util.Map;
031
032import org.forgerock.i18n.LocalizableMessage;
033import org.forgerock.i18n.LocalizableMessageBuilder;
034import org.forgerock.opendj.ldap.ResultCode;
035import org.opends.server.api.ClientConnection;
036import org.opends.server.controls.ControlDecoder;
037
038/**
039 * This interface defines a generic operation that may be processed by
040 * the Directory Server.  Specific subclasses should implement
041 * specific functionality appropriate for the type of operation.
042 * <BR><BR>
043 * Note that this class is not intended to be subclassed by any
044 * third-party code outside of the OpenDS project.  It should only be
045 * extended by the operation types included in the
046 * {@code org.opends.server.core} package.
047 */
048@org.opends.server.types.PublicAPI(
049     stability=org.opends.server.types.StabilityLevel.VOLATILE,
050     mayInstantiate=false,
051     mayExtend=false,
052     mayInvoke=true)
053public interface Operation extends Runnable
054{
055  /**
056   * Identifier used to get the local operation [if any] in the
057   * attachments.
058   */
059  String LOCALBACKENDOPERATIONS = "LocalBackendOperations";
060
061  /**
062   * Retrieves the operation type for this operation.
063   *
064   * @return  The operation type for this operation.
065   */
066  OperationType getOperationType();
067
068  /**
069   * Terminates the client connection being used to process this
070   * operation.  If this is called by a plugin, then that plugin must
071   * return a result indicating that the  client connection has been
072   * terminated.
073   *
074   * @param  disconnectReason  The disconnect reason that provides the
075   *                           generic cause for the disconnect.
076   * @param  sendNotification  Indicates whether to try to provide
077   *                           notification
078   *                           to the client that the connection will
079   *                           be closed.
080   * @param  message           The message to send to the client.  It
081   *                           may be {@code null} if no notification
082   *                           is to be sent.
083   */
084  void disconnectClient(DisconnectReason disconnectReason, boolean sendNotification, LocalizableMessage message);
085
086  /**
087   * Retrieves the client connection with which this operation is
088   * associated.
089   *
090   * @return  The client connection with which this operation is
091   *          associated.
092   */
093  ClientConnection getClientConnection();
094
095  /**
096   * Retrieves the unique identifier that is assigned to the client
097   * connection that submitted this operation.
098   *
099   * @return  The unique identifier that is assigned to the client
100   *          connection that submitted this operation.
101   */
102  long getConnectionID();
103
104  /**
105   * Retrieves the operation ID for this operation.
106   *
107   * @return  The operation ID for this operation.
108   */
109  long getOperationID();
110
111  /**
112   * Retrieves the message ID assigned to this operation.
113   *
114   * @return  The message ID assigned to this operation.
115   */
116  int getMessageID();
117
118  /**
119   * Retrieves the set of controls included in the request from the
120   * client.  The returned list must not be altered.
121   *
122   * @return  The set of controls included in the request from the
123   *          client.
124   */
125  List<Control> getRequestControls();
126
127  /**
128   * Retrieves a control included in the request from the client.
129   *
130   * @param <T>
131   *          The type of control requested.
132   * @param d
133   *          The requested control's decoder.
134   * @return The decoded form of the requested control included in the
135   *         request from the client or <code>null</code> if the
136   *         control was not found.
137   * @throws DirectoryException
138   *           if an error occurs while decoding the control.
139   */
140  <T extends Control> T getRequestControl(ControlDecoder<T> d) throws DirectoryException;
141
142  /**
143   * Adds the provided control to the set of request controls for this
144   * operation.  This method may only be called by pre-parse plugins.
145   *
146   * @param  control  The control to add to the set of request
147   *                  controls for this operation.
148   */
149  void addRequestControl(Control control);
150
151  /**
152   * Retrieves the set of controls to include in the response to the
153   * client.  The contents of this list must not be altered.
154   *
155   * @return  The set of controls to include in the response to the
156   *          client.
157   */
158  List<Control> getResponseControls();
159
160  /**
161   * Adds the provided control to the set of controls to include in
162   * the response to the client.  This method may not be called by
163   * post-response plugins.
164   *
165   * @param  control  The control to add to the set of controls to
166   *                  include in the response to the client.
167   */
168  void addResponseControl(Control control);
169
170  /**
171   * Removes the provided control from the set of controls to include
172   * in the response to the client.  This method may not be called by
173   * post-response plugins.
174   *
175   * @param  control  The control to remove from the set of controls
176   *                  to include in the response to the client.
177   */
178  void removeResponseControl(Control control);
179
180  /**
181   * Retrieves the result code for this operation.
182   *
183   * @return  The result code associated for this operation, or
184   *          {@code UNDEFINED} if the operation has not yet
185   *          completed.
186   */
187  ResultCode getResultCode();
188
189  /**
190   * Specifies the result code for this operation.  This method may
191   * not be called by post-response plugins.
192   *
193   * @param  resultCode  The result code for this operation.
194   */
195  void setResultCode(ResultCode resultCode);
196
197  /**
198   * Retrieves the real, masked result code for this operation.
199   *
200   * @return The real, masked result code associated for this operation, or
201   *         {@code UNDEFINED} if the operation has not yet completed.
202   */
203  ResultCode getMaskedResultCode();
204
205  /**
206   * Specifies the real, masked result code for this operation. This method may
207   * not be called by post-response plugins.
208   *
209   * @param maskedResultCode
210   *          The real, masked result code for this operation.
211   */
212  void setMaskedResultCode(ResultCode maskedResultCode);
213
214  /**
215   * Retrieves the error message for this operation.  Its contents may
216   * be altered by pre-parse, pre-operation, and post-operation
217   * plugins, but not by post-response plugins.
218   *
219   * @return  The error message for this operation.
220   */
221  LocalizableMessageBuilder getErrorMessage();
222
223  /**
224   * Specifies the error message for this operation.  This method may
225   * not be called by post-response plugins.
226   *
227   * @param  errorMessage  The error message for this operation.
228   */
229  void setErrorMessage(LocalizableMessageBuilder errorMessage);
230
231  /**
232   * Appends the provided message to the error message buffer.  If the
233   * buffer has not yet been created, then this will create it first
234   * and then add the provided message.  This method may not be called
235   * by post-response plugins.
236   *
237   * @param  message  The message to append to the error message
238   */
239  void appendErrorMessage(LocalizableMessage message);
240
241  /**
242   * Retrieves the real, masked error message for this operation. Its contents
243   * may be altered by pre-parse, pre-operation, and post-operation plugins, but
244   * not by post-response plugins.
245   *
246   * @return The real, masked error message for this operation.
247   */
248  LocalizableMessageBuilder getMaskedErrorMessage();
249
250  /**
251   * Specifies the real, masked error message for this operation. This method
252   * may not be called by post-response plugins.
253   *
254   * @param maskedErrorMessage
255   *          The real, masked error message for this operation.
256   */
257  void setMaskedErrorMessage(LocalizableMessageBuilder maskedErrorMessage);
258
259  /**
260   * Appends the provided message to the real, masked error message buffer. If
261   * the buffer has not yet been created, then this will create it first and
262   * then add the provided message. This method may not be called by
263   * post-response plugins.
264   *
265   * @param maskedMessage
266   *          The message to append to the real, masked error message
267   */
268  void appendMaskedErrorMessage(LocalizableMessage maskedMessage);
269
270  /**
271   * Returns an unmodifiable list containing the additional log items for this
272   * operation, which should be written to the log but not included in the
273   * response to the client.
274   *
275   * @return An unmodifiable list containing the additional log items for this
276   *         operation.
277   */
278  List<AdditionalLogItem> getAdditionalLogItems();
279
280  /**
281   * Adds an additional log item to this operation, which should be written to
282   * the log but not included in the response to the client. This method may not
283   * be called by post-response plugins.
284   *
285   * @param item
286   *          The additional log item for this operation.
287   */
288  void addAdditionalLogItem(AdditionalLogItem item);
289
290  /**
291   * Retrieves the matched DN for this operation.
292   *
293   * @return  The matched DN for this operation, or {@code null} if
294   *          the operation has not yet completed or does not have a
295   *          matched DN.
296   */
297  DN getMatchedDN();
298
299  /**
300   * Specifies the matched DN for this operation.  This may not be
301   * called by post-response plugins.
302   *
303   * @param  matchedDN  The matched DN for this operation.
304   */
305  void setMatchedDN(DN matchedDN);
306
307  /**
308   * Retrieves the set of referral URLs for this operation.  Its
309   * contents must not be altered by the caller.
310   *
311   * @return  The set of referral URLs for this operation, or
312   *          {@code null} if the operation is not yet complete or
313   *          does not have a set of referral URLs.
314   */
315  List<String> getReferralURLs();
316
317  /**
318   * Specifies the set of referral URLs for this operation.  This may
319   * not be called by post-response plugins.
320   *
321   * @param  referralURLs  The set of referral URLs for this
322   *                       operation.
323   */
324  void setReferralURLs(List<String> referralURLs);
325
326  /**
327   * Sets the response elements for this operation based on the
328   * information contained in the provided {@code DirectoryException}
329   * object.  This method may not be called by post-response plugins.
330   *
331   * @param  directoryException  The exception containing the
332   *                             information to use for the response
333   *                             elements.
334   */
335  void setResponseData(DirectoryException directoryException);
336
337  /**
338   * Indicates whether this is an internal operation rather than one
339   * that was requested by an external client.
340   *
341   * @return  {@code true} if this is an internal operation, or
342   *          {@code false} if it is not.
343   */
344  boolean isInternalOperation();
345
346  /**
347   * Specifies whether this is an internal operation rather than one
348   * that was requested by an external client.  This may not be called
349   * from within a plugin.
350   *
351   * @param  isInternalOperation  Specifies whether this is an
352   *                              internal operation rather than one
353   *                              that was requested by an external
354   *                              client.
355   */
356  void setInternalOperation(boolean isInternalOperation);
357
358  /**
359   * Indicates whether this is an inner operation rather than one that was
360   * directly requested by an external client. Said otherwise, inner operations
361   * include internal operations, but also operations in the server indirectly
362   * mandated by external requests like Rest2LDAP for example. This may not be
363   * called from within a plugin.
364   *
365   * @return {@code true} if this is an inner operation, or {@code false} if it
366   *         is not.
367   */
368  boolean isInnerOperation();
369
370  /**
371   * Specifies whether this is an inner operation rather than one that was
372   * directly requested by an external client. Said otherwise, inner operations
373   * include internal operations, but also operations in the server indirectly
374   * mandated by external requests like Rest2LDAP for example. This may not be
375   * called from within a plugin.
376   *
377   * @param isInnerOperation
378   *          Specifies whether this is an inner operation rather than one that
379   *          was requested by an external client.
380   */
381  void setInnerOperation(boolean isInnerOperation);
382
383  /**
384   * Indicates whether this is a synchronization operation rather than
385   * one that was requested by an external client.
386   *
387   * @return  {@code true} if this is a data synchronization
388   *          operation, or {@code false} if it is not.
389   */
390  boolean isSynchronizationOperation();
391
392  /**
393   * Specifies whether this is a synchronization operation rather than
394   * one that was requested by an external client.  This method may
395   * not be called from within a plugin.
396   *
397   * @param  isSynchronizationOperation  Specifies whether this is a
398   *                                     synchronization operation
399   *                                     rather than one that was
400   *                                     requested by an external
401   *                                     client.
402   */
403  void setSynchronizationOperation(boolean isSynchronizationOperation);
404
405  /**
406   * Specifies whether this operation must be synchronized to other
407   * copies of the data.
408   *
409   * @param  dontSynchronize  Specifies whether this operation must be
410   *                          synchronized to other copies
411   *                          of the data.
412   */
413  void setDontSynchronize(boolean dontSynchronize);
414
415  /**
416   * Retrieves the entry for the user that should be considered the
417   * authorization identity for this operation.  In many cases, it
418   * will be the same as the authorization entry for the underlying
419   * client connection, or {@code null} if no authentication has been
420   * performed on that connection.  However, it may be some other
421   * value if special processing has been requested (e.g., the
422   * operation included a proxied authorization control).  This method
423   * should not be called by pre-parse plugins because the correct
424   * value may not yet have been determined.
425   *
426   * @return  The entry for the user that should be considered the
427   *          authorization identity for this operation, or
428   *          {@code null} if the authorization identity should be the
429   *          unauthenticated  user.
430   */
431  Entry getAuthorizationEntry();
432
433  /**
434   * Provides the entry for the user that should be considered the
435   * authorization identity for this operation.  This must not be
436   * called from within a plugin.
437   *
438   * @param  authorizationEntry  The entry for the user that should be
439   *                             considered the authorization identity
440   *                             for this operation, or {@code null}
441   *                             if it should be the unauthenticated
442   *                             user.
443   */
444  void setAuthorizationEntry(Entry authorizationEntry);
445
446  /**
447   * Retrieves the authorization DN for this operation.  In many
448   * cases, it will be the same as the DN of the authenticated user
449   * for the underlying connection, or the null DN if no
450   * authentication has been performed on that connection.  However,
451   * it may be some other value if special processing has been
452   * requested (e.g., the operation included a proxied authorization
453   * control).  This method should not be called by pre-parse plugins
454   * because the correct value may not have yet been determined.
455   *
456   * @return  The authorization DN for this operation, or the null DN
457   *          if it should be the unauthenticated user..
458   */
459  DN getAuthorizationDN();
460
461  /**
462   * Retrieves the proxied authorization DN for this operation if proxied
463   * authorization has been requested.
464   *
465   * @return  The proxied authorization DN for this operation if proxied
466   *          authorization has been requested, or {@code null} if proxied
467   *          authorization has not been requested.
468   */
469  DN getProxiedAuthorizationDN();
470
471  /**
472   * Set the proxied authorization DN for this operation if proxied
473   * authorization has been requested.
474   *
475   * @param proxiedAuthorizationDN
476   *          The proxied authorization DN for this operation if proxied
477   *          authorization has been requested, or {@code null} if proxied
478   *          authorization has not been requested.
479   */
480  void setProxiedAuthorizationDN(DN proxiedAuthorizationDN);
481
482  /**
483   * Retrieves the set of attachments defined for this operation, as a
484   * mapping between the attachment name and the associated object.
485   *
486   * @return  The set of attachments defined for this operation.
487   */
488  Map<String, Object> getAttachments();
489
490  /**
491   * Retrieves the attachment with the specified name.
492   *
493   * @param <T> the type of the attached object
494   * @param  name  The name for the attachment to retrieve.  It will
495   *               be treated in a case-sensitive manner.
496   *
497   * @return  The requested attachment object, or {@code null} if it
498   *          does not exist.
499   */
500  <T> T getAttachment(String name);
501
502  /**
503   * Removes the attachment with the specified name.
504   *
505   * @param <T> the type of the attached object
506   * @param  name  The name for the attachment to remove.  It will be
507   *               treated in a case-sensitive manner.
508   *
509   * @return  The attachment that was removed, or {@code null} if it
510   *          does not exist.
511   */
512  <T> T removeAttachment(String name);
513
514  /**
515   * Sets the value of the specified attachment.  If an attachment
516   * already exists with the same name, it will be replaced.
517   * Otherwise, a new attachment will be added.
518   *
519   * @param <T> the type of the attached object
520   * @param  name   The name to use for the attachment.
521   * @param  value  The value to use for the attachment.
522   *
523   * @return  The former value held by the attachment with the given
524   *          name, or {@code null} if there was previously no such
525   *          attachment.
526   */
527  <T> T setAttachment(String name, Object value);
528
529  /**
530   * Retrieves the time that processing started for this operation.
531   *
532   * @return  The time that processing started for this operation.
533   */
534  long getProcessingStartTime();
535
536  /**
537   * Retrieves the time that processing stopped for this operation.
538   * This will actually hold a time immediately before the response
539   * was sent to the client.
540   *
541   * @return  The time that processing stopped for this operation.
542   */
543  long getProcessingStopTime();
544
545  /**
546   * Retrieves the length of time in milliseconds that the server
547   * spent processing this operation.  This should not be called until
548   * after the server has sent the response to the client.
549   *
550   * @return  The length of time in milliseconds that the server spent
551   *          processing this operation.
552   */
553  long getProcessingTime();
554
555  /**
556   * Retrieves the length of time in nanoseconds that
557   * the server spent processing this operation if available.
558   * This should not be called until after the server has sent the
559   * response to the client.
560   *
561   * @return  The length of time in nanoseconds that the server
562   *          spent processing this operation or -1 if its not
563   *          available.
564   */
565  long getProcessingNanoTime();
566
567  /**
568   * Indicates that processing on this operation has completed
569   * successfully and that the client should perform any associated
570   * cleanup work.
571   */
572  void operationCompleted();
573
574  /**
575   * Attempts to cancel this operation before processing has
576   * completed.
577   *
578   * @param  cancelRequest  Information about the way in which the
579   *                        operation should be canceled.
580   *
581   * @return  A code providing information on the result of the
582   *          cancellation.
583   */
584  CancelResult cancel(CancelRequest cancelRequest);
585
586  /**
587   * Attempts to abort this operation before processing has
588   * completed.
589   *
590   * @param  cancelRequest  Information about the way in which the
591   *                        operation should be canceled.
592   */
593  void abort(CancelRequest cancelRequest);
594
595  /**
596   * Retrieves the cancel request that has been issued for this
597   * operation, if there is one.  This method should not be called by
598   * post-operation or post-response plugins.
599   *
600   * @return  The cancel request that has been issued for this
601   *          operation, or {@code null} if there has not been any
602   *          request to cancel.
603   */
604  CancelRequest getCancelRequest();
605
606  /**
607   * Retrieves the cancel result for this operation.
608   *
609   * @return  The cancel result for this operation.  It will be
610   *          {@code null} if the operation has not seen and reacted
611   *          to a cancel request.
612   */
613  CancelResult getCancelResult();
614
615  /**
616   * Retrieves a string representation of this operation.
617   *
618   * @return  A string representation of this operation.
619   */
620  @Override String toString();
621
622  /**
623   * Appends a string representation of this operation to the provided
624   * buffer.
625   *
626   * @param  buffer  The buffer into which a string representation of
627   *                 this operation should be appended.
628   */
629  void toString(StringBuilder buffer);
630
631  /**
632   * Indicates whether this operation needs to be synchronized to
633   * other copies of the data.
634   *
635   * @return  {@code true} if this operation should not be
636   *          synchronized, or {@code false} if it should be
637   *          synchronized.
638   */
639  boolean dontSynchronize();
640
641  /**
642   * Set the attachments to the operation.
643   *
644   * @param attachments - Attachments to register within the
645   *                      operation
646   */
647  void setAttachments(Map<String, Object> attachments);
648
649  /**
650   * Checks to see if this operation requested to cancel in which case
651   * CanceledOperationException will be thrown.
652   *
653   * @param signalTooLate <code>true</code> to signal that any further
654   *                      cancel requests will be too late after
655   *                      return from this call or <code>false</code>
656   *                      otherwise.
657   *
658   * @throws CanceledOperationException if this operation should
659   * be cancelled.
660   */
661  void checkIfCanceled(boolean signalTooLate) throws CanceledOperationException;
662
663  /**
664   * Registers a callback which should be run once this operation has
665   * completed and the response sent back to the client.
666   *
667   * @param callback
668   *          The callback to be run once this operation has completed
669   *          and the response sent back to the client.
670   */
671  void registerPostResponseCallback(Runnable callback);
672
673  /**
674   * Performs the work of actually processing this operation. This should
675   * include all processing for the operation, including invoking pre-parse and
676   * post-response plugins, logging messages and any other work that might need
677   * to be done in the course of processing.
678   */
679  @Override
680  void run();
681}
682