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