001/*
002 * Copyright 2016-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2016-2024 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2016-2024 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.sdk.unboundidds.tasks;
037
038
039
040import java.util.ArrayList;
041import java.util.Arrays;
042import java.util.Collection;
043import java.util.Collections;
044import java.util.Date;
045import java.util.LinkedHashMap;
046import java.util.List;
047import java.util.Map;
048
049import com.unboundid.ldap.sdk.Attribute;
050import com.unboundid.ldap.sdk.Entry;
051import com.unboundid.util.NotMutable;
052import com.unboundid.util.NotNull;
053import com.unboundid.util.Nullable;
054import com.unboundid.util.StaticUtils;
055import com.unboundid.util.ThreadSafety;
056import com.unboundid.util.ThreadSafetyLevel;
057
058import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*;
059
060
061
062/**
063 * This class defines a Directory Server task that can be used to trigger the
064 * rotation of one or more log files.
065 * <BR>
066 * <BLOCKQUOTE>
067 *   <B>NOTE:</B>  This class, and other classes within the
068 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
069 *   supported for use against Ping Identity, UnboundID, and
070 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
071 *   for proprietary functionality or for external specifications that are not
072 *   considered stable or mature enough to be guaranteed to work in an
073 *   interoperable way with other types of LDAP servers.
074 * </BLOCKQUOTE>
075 * <BR>
076 * The properties that are available for use with this type of task include:
077 * <UL>
078 *   <LI>The path to the log file to be rotated.  It may be either an absolute
079 *       path or a path that is relative to the server root.  Multiple log files
080 *       may be targeted by specifying multiple paths, and if no paths are given
081 *       then the server will rotate all log files.</LI>
082 * </UL>
083 */
084@NotMutable()
085@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
086public final class RotateLogTask
087       extends Task
088{
089  /**
090   * The fully-qualified name of the Java class that is used for the rotate log
091   * task.
092   */
093  @NotNull static final String ROTATE_LOG_TASK_CLASS =
094       "com.unboundid.directory.server.tasks.RotateLogTask";
095
096
097
098  /**
099   * The name of the attribute used to specify the path to a log file to rotate.
100   */
101  @NotNull private static final String ATTR_PATH = "ds-task-rotate-log-path";
102
103
104
105  /**
106   * The name of the object class used in rotate log task entries.
107   */
108  @NotNull private static final String OC_ROTATE_LOG_TASK =
109       "ds-task-rotate-log";
110
111
112
113  /**
114   * The task property that will be used for the log file path.
115   */
116  @NotNull private static final TaskProperty PROPERTY_PATH = new TaskProperty(
117       ATTR_PATH, INFO_ROTATE_LOG_DISPLAY_NAME_PATH.get(),
118       INFO_ROTATE_LOG_DESCRIPTION_PATH.get(), String.class, false, true,
119       false);
120
121
122
123  /**
124   * The serial version UID for this serializable class.
125   */
126  private static final long serialVersionUID = -7737121245254808139L;
127
128
129
130  // The paths of the log files to rotate.
131  @NotNull private final List<String> paths;
132
133
134
135  /**
136   * Creates a new uninitialized rotate log task instance that should only be
137   * used for obtaining general information about this task, including the task
138   * name, description, and supported properties.  Attempts to use a task
139   * created with this constructor for any other reason will likely fail.
140   */
141  public RotateLogTask()
142  {
143    paths = null;
144  }
145
146
147
148  /**
149   * Creates a new rotate log task with the provided information.
150   *
151   * @param  taskID  The task ID to use for this task.  If it is {@code null}
152   *                 then a UUID will be generated for use as the task ID.
153   * @param  paths   The paths (on the server filesystem) of the log files to
154   *                 rotate.  The paths may be either absolute or relative to
155   *                 the server root.  This may be {@code null} or empty if the
156   *                 server should rotate all appropriate log files.
157   */
158  public RotateLogTask(@Nullable final String taskID,
159                       @Nullable final String... paths)
160  {
161    this(taskID, null, null, null, null, null, paths);
162  }
163
164
165
166  /**
167   * Creates a new rotate log task with the provided information.
168   *
169   * @param  taskID  The task ID to use for this task.  If it is {@code null}
170   *                 then a UUID will be generated for use as the task ID.
171   * @param  paths   The paths (on the server filesystem) of the log files to
172   *                 rotate.  The paths may be either absolute or relative to
173   *                 the server root.  This may be {@code null} or empty if the
174   *                 server should rotate all appropriate log files.
175   */
176  public RotateLogTask(@Nullable final String taskID,
177                       @Nullable final Collection<String> paths)
178  {
179    this(taskID, null, null, null, null, null, paths);
180  }
181
182
183
184  /**
185   * Creates a new rotate log task with the provided information.
186   *
187   * @param  taskID                  The task ID to use for this task.  If it is
188   *                                 {@code null} then a UUID will be generated
189   *                                 for use as the task ID.
190   * @param  scheduledStartTime      The time that this task should start
191   *                                 running.
192   * @param  dependencyIDs           The list of task IDs that will be required
193   *                                 to complete before this task will be
194   *                                 eligible to start.
195   * @param  failedDependencyAction  Indicates what action should be taken if
196   *                                 any of the dependencies for this task do
197   *                                 not complete successfully.
198   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
199   *                                 that should be notified when this task
200   *                                 completes.
201   * @param  notifyOnError           The list of e-mail addresses of individuals
202   *                                 that should be notified if this task does
203   *                                 not complete successfully.
204   * @param  paths                   The paths (on the server filesystem) of the
205   *                                 log files to rotate.  The paths may be
206   *                                 either absolute or relative to the server
207   *                                 root.  This may be {@code null} or empty if
208   *                                 the server should rotate all appropriate
209   *                                 log files.
210   */
211  public RotateLogTask(@Nullable final String taskID,
212              @Nullable final Date scheduledStartTime,
213              @Nullable final List<String> dependencyIDs,
214              @Nullable final FailedDependencyAction failedDependencyAction,
215              @Nullable final List<String> notifyOnCompletion,
216              @Nullable final List<String> notifyOnError,
217              @Nullable final String... paths)
218  {
219    this(taskID, scheduledStartTime, dependencyIDs, failedDependencyAction,
220         notifyOnCompletion, notifyOnError, StaticUtils.toList(paths));
221  }
222
223
224
225  /**
226   * Creates a new rotate log task with the provided information.
227   *
228   * @param  taskID                  The task ID to use for this task.  If it is
229   *                                 {@code null} then a UUID will be generated
230   *                                 for use as the task ID.
231   * @param  scheduledStartTime      The time that this task should start
232   *                                 running.
233   * @param  dependencyIDs           The list of task IDs that will be required
234   *                                 to complete before this task will be
235   *                                 eligible to start.
236   * @param  failedDependencyAction  Indicates what action should be taken if
237   *                                 any of the dependencies for this task do
238   *                                 not complete successfully.
239   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
240   *                                 that should be notified when this task
241   *                                 completes.
242   * @param  notifyOnError           The list of e-mail addresses of individuals
243   *                                 that should be notified if this task does
244   *                                 not complete successfully.
245   * @param  paths                   The paths (on the server filesystem) of the
246   *                                 log files to rotate.  The paths may be
247   *                                 either absolute or relative to the server
248   *                                 root.  This may be {@code null} or empty if
249   *                                 the server should rotate all appropriate
250   *                                 log files.
251   */
252  public RotateLogTask(@Nullable final String taskID,
253              @Nullable final Date scheduledStartTime,
254              @Nullable final List<String> dependencyIDs,
255              @Nullable final FailedDependencyAction failedDependencyAction,
256              @Nullable final List<String> notifyOnCompletion,
257              @Nullable final List<String> notifyOnError,
258              @Nullable final Collection<String> paths)
259  {
260    this(taskID, scheduledStartTime, dependencyIDs, failedDependencyAction,
261         null, notifyOnCompletion, null, notifyOnError, null, null, null,
262         paths);
263  }
264
265
266
267  /**
268   * Creates a new rotate log task with the provided information.
269   *
270   * @param  taskID                  The task ID to use for this task.  If it is
271   *                                 {@code null} then a UUID will be generated
272   *                                 for use as the task ID.
273   * @param  scheduledStartTime      The time that this task should start
274   *                                 running.
275   * @param  dependencyIDs           The list of task IDs that will be required
276   *                                 to complete before this task will be
277   *                                 eligible to start.
278   * @param  failedDependencyAction  Indicates what action should be taken if
279   *                                 any of the dependencies for this task do
280   *                                 not complete successfully.
281   * @param  notifyOnStart           The list of e-mail addresses of individuals
282   *                                 that should be notified when this task
283   *                                 starts running.
284   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
285   *                                 that should be notified when this task
286   *                                 completes.
287   * @param  notifyOnSuccess         The list of e-mail addresses of individuals
288   *                                 that should be notified if this task
289   *                                 completes successfully.
290   * @param  notifyOnError           The list of e-mail addresses of individuals
291   *                                 that should be notified if this task does
292   *                                 not complete successfully.
293   * @param  alertOnStart            Indicates whether the server should send an
294   *                                 alert notification when this task starts.
295   * @param  alertOnSuccess          Indicates whether the server should send an
296   *                                 alert notification if this task completes
297   *                                 successfully.
298   * @param  alertOnError            Indicates whether the server should send an
299   *                                 alert notification if this task fails to
300   *                                 complete successfully.
301   * @param  paths                   The paths (on the server filesystem) of the
302   *                                 log files to rotate.  The paths may be
303   *                                 either absolute or relative to the server
304   *                                 root.  This may be {@code null} or empty if
305   *                                 the server should rotate all appropriate
306   *                                 log files.
307   */
308  public RotateLogTask(@Nullable final String taskID,
309              @Nullable final Date scheduledStartTime,
310              @Nullable final List<String> dependencyIDs,
311              @Nullable final FailedDependencyAction failedDependencyAction,
312              @Nullable final List<String> notifyOnStart,
313              @Nullable final List<String> notifyOnCompletion,
314              @Nullable final List<String> notifyOnSuccess,
315              @Nullable final List<String> notifyOnError,
316              @Nullable final Boolean alertOnStart,
317              @Nullable final Boolean alertOnSuccess,
318              @Nullable final Boolean alertOnError,
319              @Nullable final Collection<String> paths)
320  {
321    super(taskID, ROTATE_LOG_TASK_CLASS, scheduledStartTime, dependencyIDs,
322         failedDependencyAction, notifyOnStart, notifyOnCompletion,
323         notifyOnSuccess, notifyOnError, alertOnStart, alertOnSuccess,
324         alertOnError);
325
326    if (paths == null)
327    {
328      this.paths = Collections.emptyList();
329    }
330    else
331    {
332      this.paths = Collections.unmodifiableList(new ArrayList<>(paths));
333    }
334  }
335
336
337
338  /**
339   * Creates a new rotate log task from the provided entry.
340   *
341   * @param  entry  The entry to use to create this rotate log task.
342   *
343   * @throws  TaskException  If the provided entry cannot be parsed as a rotate
344   *                         log task entry.
345   */
346  public RotateLogTask(@NotNull final Entry entry)
347         throws TaskException
348  {
349    super(entry);
350
351    // Get the log file paths, if present.
352    final String[] pathValues = entry.getAttributeValues(ATTR_PATH);
353    if (pathValues == null)
354    {
355      paths = Collections.emptyList();
356    }
357    else
358    {
359      paths = Collections.unmodifiableList(new ArrayList<>(
360           Arrays.asList(pathValues)));
361    }
362  }
363
364
365
366  /**
367   * Creates a new rotate log task from the provided set of task properties.
368   *
369   * @param  properties  The set of task properties and their corresponding
370   *                     values to use for the task.  It must not be
371   *                     {@code null}.
372   *
373   * @throws  TaskException  If the provided set of properties cannot be used to
374   *                         create a valid rotate log task.
375   */
376  public RotateLogTask(@NotNull final Map<TaskProperty,List<Object>> properties)
377         throws TaskException
378  {
379    super(ROTATE_LOG_TASK_CLASS, properties);
380
381    String[] pathArray = StaticUtils.NO_STRINGS;
382    for (final Map.Entry<TaskProperty,List<Object>> entry :
383         properties.entrySet())
384    {
385      final TaskProperty p = entry.getKey();
386      final String attrName = p.getAttributeName();
387      final List<Object> values = entry.getValue();
388
389      if (attrName.equalsIgnoreCase(ATTR_PATH))
390      {
391        pathArray = parseStrings(p, values, pathArray);
392      }
393    }
394
395    paths = Collections.unmodifiableList(Arrays.asList(pathArray));
396  }
397
398
399
400  /**
401   * {@inheritDoc}
402   */
403  @Override()
404  @NotNull()
405  public String getTaskName()
406  {
407    return INFO_TASK_NAME_ROTATE_LOG.get();
408  }
409
410
411
412  /**
413   * {@inheritDoc}
414   */
415  @Override()
416  @NotNull()
417  public String getTaskDescription()
418  {
419    return INFO_TASK_DESCRIPTION_ROTATE_LOG.get();
420  }
421
422
423
424  /**
425   * Retrieves the paths of the log files to rotate.  The paths may be
426   * absolute or relative to the server root.
427   *
428   * @return  The paths of the log files to rotate, or an empty list if no
429   *          paths were specified and the server should rotate the log files
430   *          for all applicable loggers.
431   */
432  @NotNull()
433  public List<String> getPaths()
434  {
435    return paths;
436  }
437
438
439
440  /**
441   * {@inheritDoc}
442   */
443  @Override()
444  @NotNull()
445  protected List<String> getAdditionalObjectClasses()
446  {
447    return Collections.singletonList(OC_ROTATE_LOG_TASK);
448  }
449
450
451
452  /**
453   * {@inheritDoc}
454   */
455  @Override()
456  @NotNull()
457  protected List<Attribute> getAdditionalAttributes()
458  {
459    if (paths.isEmpty())
460    {
461      return Collections.emptyList();
462    }
463    else
464    {
465      return Collections.singletonList(new Attribute(ATTR_PATH, paths));
466    }
467  }
468
469
470
471  /**
472   * {@inheritDoc}
473   */
474  @Override()
475  @NotNull()
476  public List<TaskProperty> getTaskSpecificProperties()
477  {
478    return Collections.singletonList(PROPERTY_PATH);
479  }
480
481
482
483  /**
484   * {@inheritDoc}
485   */
486  @Override()
487  @NotNull()
488  public Map<TaskProperty,List<Object>> getTaskPropertyValues()
489  {
490    final LinkedHashMap<TaskProperty,List<Object>> props =
491         new LinkedHashMap<>(StaticUtils.computeMapCapacity(10));
492
493
494    if (! paths.isEmpty())
495    {
496      props.put(PROPERTY_PATH, Collections.<Object>unmodifiableList(paths));
497    }
498
499    props.putAll(super.getTaskPropertyValues());
500    return Collections.unmodifiableMap(props);
501  }
502}