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 * docs/licenses/cddl.txt
011 * or http://www.opensource.org/licenses/cddl1.php.
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 * docs/licenses/cddl.txt.  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 *      Portions Copyright 2010-2024 Ping Identity Corporation
026 */
027package com.unboundid.directory.sdk.ds.api;
028
029
030
031import java.util.Collections;
032import java.util.List;
033import java.util.Map;
034
035import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider;
036import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
037import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension;
038import com.unboundid.directory.sdk.ds.types.DirectoryServerContext;
039import com.unboundid.directory.sdk.ds.types.TaskContext;
040import com.unboundid.directory.sdk.ds.types.TaskReturnState;
041import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension;
042import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension;
043import com.unboundid.ldap.sdk.LDAPException;
044import com.unboundid.util.Extensible;
045import com.unboundid.util.ThreadSafety;
046import com.unboundid.util.ThreadSafetyLevel;
047import com.unboundid.util.args.ArgumentException;
048import com.unboundid.util.args.ArgumentParser;
049
050
051
052/**
053 * This class defines an API that must be implemented by extensions which
054 * may be used as administrative tasks.  Administrative tasks have the ability
055 * to perform arbitrary processing within the server whenever a particular kind
056 * of entry is added, and that processing can be performed immediately or at
057 * some specified time in the future.  The server must be configured as follows
058 * to allow creation of third-party tasks:
059 * <PRE>
060 *   dsconfig set-global-configuration-prop
061 *     --add allowed-task:com.unboundid.directory.sdk.extensions.ThirdPartyTask
062 * </PRE>
063 * Tasks may then be scheduled by adding an entry
064 * below "cn=Scheduled Tasks,cn=tasks" with a format like the following:
065 * <PRE>
066 *   dn:  ds-task-id=TASKID,cn=Scheduled Tasks,cn=tasks
067 *   objectClass: top
068 *   objectClass: ds-task
069 *   objectClass: ds-third-party-task
070 *   ds-task-id: TASKID
071 *   ds-task-class-name: com.unboundid.directory.sdk.extensions.ThirdPartyTask
072 *   ds-third-party-task-java-class: com.example.ExampleTask
073 *   ds-third-party-task-argument: name=value
074 * </PRE>
075 * In this example, TASKID should be replaced with a string that uniquely
076 * identifies the task.  The value of the ds-third-party-task-java-class
077 * attribute should contain the fully-qualified name of the non-abstract Java
078 * class that extends this com.unboundid.directory.sdk.api.Task class, and the
079 * ds-third-party-task-argument values (if any) should reflect the set of
080 * arguments allowed for the task as per the {@link #defineConfigArguments}
081 * method.
082 * <BR><BR>
083 * Alternately, the com.unboundid.ldap.sdk.unboundidds.tasks.ThirdPartyTask
084 * class included in the Commercial Edition of the UnboundID LDAP SDK for Java
085 * may be used to schedule and interact with these kinds of tasks.  See the
086 * documentation for the Commercial Edition of the LDAP SDK for more
087 * information on using the UnboundID LDAP SDK for Java to schedule and interact
088 * with administrative tasks.
089 *
090 * @see  com.unboundid.directory.sdk.ds.scripting.ScriptedTask
091 */
092@Extensible()
093@DirectoryServerExtension()
094@DirectoryProxyServerExtension(appliesToLocalContent=true,
095     appliesToRemoteContent=false)
096@SynchronizationServerExtension(appliesToLocalContent=true,
097     appliesToSynchronizedContent=false)
098@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
099public abstract class Task
100       implements UnboundIDExtension, ExampleUsageProvider
101{
102  /**
103   * Creates a new instance of this task.  All task implementations must include
104   * a default constructor, but any initialization should generally be done in
105   * the {@code initializeTask} method.
106   */
107  public Task()
108  {
109    // No implementation is required.
110  }
111
112
113
114  /**
115   * {@inheritDoc}
116   */
117  public abstract String getExtensionName();
118
119
120
121  /**
122   * {@inheritDoc}
123   */
124  public abstract String[] getExtensionDescription();
125
126
127
128  /**
129   * {@inheritDoc}
130   */
131  public void defineConfigArguments(final ArgumentParser parser)
132         throws ArgumentException
133  {
134    // No arguments will be allowed by default.
135  }
136
137
138
139  /**
140   * Initializes this task.
141   *
142   * @param  serverContext  A handle to the server context for the server in
143   *                        which this task is running.
144   * @param  parser         The argument parser which has been initialized from
145   *                        the configuration for this task.
146   *
147   * @throws  LDAPException  If a problem occurs while initializing this task.
148   */
149  public void initializeTask(final DirectoryServerContext serverContext,
150                             final ArgumentParser parser)
151         throws LDAPException
152  {
153    // No initialization will be performed by default.
154  }
155
156
157
158  /**
159   * Retrieves a human-readable name that may be used for this task.
160   *
161   * @return  A human-readable name that may be used for this task.
162   */
163  public abstract String getTaskName();
164
165
166
167  /**
168   * Performs the appropriate processing for this task.
169   *
170   * @param  taskContext  Information about the task to be run.
171   *
172   * @return  Information about the state of the task after processing has
173   *          completed.
174   */
175  public abstract TaskReturnState runTask(final TaskContext taskContext);
176
177
178
179  /**
180   * Indicates whether this task may be interrupted before it has completed
181   * (e.g., canceled by an administrator or aborted at server shutdown).  It is
182   * particularly important that potentially long-running tasks be interruptible
183   * so that they do not impede server shutdown or consume excessive resources.
184   *
185   * @return  {@code true} if this task may be interrupted before it has
186   *          completed, or {@code false} if it cannot be interrupted.
187   */
188  public boolean isInterruptible()
189  {
190    return false;
191  }
192
193
194
195  /**
196   * Attempts to interrupt the execution of this task.  This should only be
197   * called if the {@link #isInterruptible} method returns {@code true}.
198   *
199   * @param  interruptState   The return state that should be used for the task
200   *                          if it is successfully interrupted.
201   * @param  interruptReason  A message that provides a reason that the task has
202   *                          been interrupted.
203   */
204  public void interruptTask(final TaskReturnState interruptState,
205                            final String interruptReason)
206  {
207    // No action is performed by default.
208  }
209
210
211
212  /**
213   * {@inheritDoc}
214   */
215  public Map<List<String>,String> getExamplesArgumentSets()
216  {
217    return Collections.emptyMap();
218  }
219}