001/*
002 * Copyright 2020-2022 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2020-2022 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) 2020-2022 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.io.Serializable;
041import java.util.ArrayList;
042import java.util.Date;
043import java.util.Iterator;
044import java.util.List;
045import java.util.concurrent.TimeUnit;
046
047import com.unboundid.util.Debug;
048import com.unboundid.util.Mutable;
049import com.unboundid.util.NotNull;
050import com.unboundid.util.Nullable;
051import com.unboundid.util.ThreadSafety;
052import com.unboundid.util.ThreadSafetyLevel;
053import com.unboundid.util.args.ArgumentException;
054import com.unboundid.util.args.DurationArgument;
055
056
057
058/**
059 * This class defines a set of properties that may be used when creating a
060 * {@link CollectSupportDataTask}.
061 * <BR>
062 * <BLOCKQUOTE>
063 *   <B>NOTE:</B>  This class, and other classes within the
064 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
065 *   supported for use against Ping Identity, UnboundID, and
066 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
067 *   for proprietary functionality or for external specifications that are not
068 *   considered stable or mature enough to be guaranteed to work in an
069 *   interoperable way with other types of LDAP servers.
070 * </BLOCKQUOTE>
071 */
072@Mutable()
073@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
074public final class CollectSupportDataTaskProperties
075       implements Serializable
076{
077  /**
078   * The serial version UID for this serializable class.
079   */
080  private static final long serialVersionUID = 1424492798476859173L;
081
082
083
084  // Indicates whether to generate an administrative alert if the task completes
085  // with an error.
086  @Nullable private Boolean alertOnError;
087
088  // Indicates whether to generate an administrative alert when the task starts
089  // running.
090  @Nullable private Boolean alertOnStart;
091
092  // Indicates whether to generate an administrative alert if the task completes
093  // successfully.
094  @Nullable private Boolean alertOnSuccess;
095
096  // Indicates whether to include binary files in the support data archive.
097  @Nullable private Boolean includeBinaryFiles;
098
099  // Indicates whether to include expensive data in the support data archive.
100  @Nullable private Boolean includeExpensiveData;
101
102  // Indicates whether to include third-party extension source code in the
103  // support data archive.
104  @Nullable private Boolean includeExtensionSource;
105
106  // Indicates whether to include a replication state dump in the support data
107  // archive.
108  @Nullable private Boolean includeReplicationStateDump;
109
110  // Indicates whether to capture information sequentially rather than in
111  // parallel.
112  @Nullable private Boolean useSequentialMode;
113
114  // The security level to use for data included in the support data archive.
115  @Nullable private CollectSupportDataSecurityLevel securityLevel;
116
117  // The time at which the task should start running.
118  @Nullable private Date scheduledStartTime;
119
120  // The action to take if any of the dependencies for this task complete
121  // unsuccessfully.
122  @Nullable private FailedDependencyAction failedDependencyAction;
123
124  // The number of jstacks to include in the support data archive.
125  @Nullable private Integer jstackCount;
126
127  // The amount of data in kilobytes to capture from the beginning of each log
128  // file.
129  @Nullable private Integer logFileHeadCollectionSizeKB;
130
131  // The amount of data in kilobytes to capture from the end of each log file.
132  @Nullable private Integer logFileTailCollectionSizeKB;
133
134  // The report count to use for sampled metrics.
135  @Nullable private Integer reportCount;
136
137  // The report interval in seconds to use for sampled metrics.
138  @Nullable private Integer reportIntervalSeconds;
139
140  // The minimum number of existing support data archives that should be
141  // retained.
142  @Nullable private Integer retainPreviousSupportDataArchiveCount;
143
144  // The dependency IDs of any tasks on which the collect support data task
145  // should depend.
146  @NotNull private final List<String> dependencyIDs;
147
148  // The addresses to email whenever the task completes, regardless of success
149  // or failure.
150  @NotNull private final List<String> notifyOnCompletion;
151
152  // The addresses to email if the task completes with an error.
153  @NotNull private final List<String> notifyOnError;
154
155  // The addresses to email when the task starts.
156  @NotNull private final List<String> notifyOnStart;
157
158  // The addresses to email if the task completes successfully.
159  @NotNull private final List<String> notifyOnSuccess;
160
161  // A comment to include in the support data archive.
162  @Nullable private String comment;
163
164  // The path to the encryption passphrase file.
165  @Nullable private String encryptionPassphraseFile;
166
167  // A string representation of the log duration to capture.
168  @Nullable private String logDuration;
169
170  // The path to which the support data archive should be written.
171  @Nullable private String outputPath;
172
173  // The minimum age for existing support data archives that should be retained.
174  @Nullable private String retainPreviousSupportDataArchiveAge;
175
176  // The task ID to use for the collect support data task.
177  @Nullable private String taskID;
178
179
180
181  /**
182   * Creates a new set of collect support data task properties without any of
183   * the properties set (so that the server will use default values for all of
184   * them).
185   */
186  public CollectSupportDataTaskProperties()
187  {
188    alertOnError = null;
189    alertOnStart = null;
190    alertOnSuccess = null;
191    includeBinaryFiles = null;
192    includeExpensiveData = null;
193    includeExtensionSource = null;
194    includeReplicationStateDump = null;
195    useSequentialMode = null;
196    securityLevel = null;
197    scheduledStartTime = null;
198    failedDependencyAction = null;
199    jstackCount = null;
200    logFileHeadCollectionSizeKB = null;
201    logFileTailCollectionSizeKB = null;
202    reportCount = null;
203    reportIntervalSeconds = null;
204    retainPreviousSupportDataArchiveCount = null;
205    dependencyIDs = new ArrayList<>(5);
206    notifyOnCompletion = new ArrayList<>(5);
207    notifyOnError = new ArrayList<>(5);
208    notifyOnStart = new ArrayList<>(5);
209    notifyOnSuccess = new ArrayList<>(5);
210    comment = null;
211    encryptionPassphraseFile = null;
212    logDuration = null;
213    outputPath = null;
214    retainPreviousSupportDataArchiveAge = null;
215    taskID = null;
216  }
217
218
219
220  /**
221   * Creates a new set of collect support data task properties as a copy of the
222   * provided properties.
223   *
224   * @param  properties  The collect support data task properties to duplicate.
225   */
226  public CollectSupportDataTaskProperties(
227              @NotNull final CollectSupportDataTaskProperties properties)
228  {
229    alertOnError = properties.getAlertOnError();
230    alertOnStart = properties.getAlertOnStart();
231    alertOnSuccess = properties.getAlertOnSuccess();
232    includeBinaryFiles = properties.getIncludeBinaryFiles();
233    includeExpensiveData = properties.getIncludeExpensiveData();
234    includeExtensionSource = properties.getIncludeExtensionSource();
235    includeReplicationStateDump = properties.getIncludeReplicationStateDump();
236    useSequentialMode = properties.getUseSequentialMode();
237    securityLevel = properties.getSecurityLevel();
238    scheduledStartTime = properties.getScheduledStartTime();
239    failedDependencyAction = properties.getFailedDependencyAction();
240    jstackCount = properties.getJStackCount();
241    logFileHeadCollectionSizeKB = properties.getLogFileHeadCollectionSizeKB();
242    logFileTailCollectionSizeKB = properties.getLogFileTailCollectionSizeKB();
243    reportCount = properties.getReportCount();
244    reportIntervalSeconds = properties.getReportIntervalSeconds();
245    retainPreviousSupportDataArchiveCount =
246         properties.getRetainPreviousSupportDataArchiveCount();
247    dependencyIDs = new ArrayList<>(properties.getDependencyIDs());
248    notifyOnCompletion = new ArrayList<>(properties.getNotifyOnCompletion());
249    notifyOnError = new ArrayList<>(properties.getNotifyOnError());
250    notifyOnStart = new ArrayList<>(properties.getNotifyOnStart());
251    notifyOnSuccess = new ArrayList<>(properties.getNotifyOnSuccess());
252    comment = properties.getComment();
253    encryptionPassphraseFile = properties.getEncryptionPassphraseFile();
254    logDuration = properties.getLogDuration();
255    outputPath = properties.getOutputPath();
256    retainPreviousSupportDataArchiveAge =
257         properties.getRetainPreviousSupportDataArchiveAge();
258    taskID = properties.getTaskID();
259  }
260
261
262
263  /**
264   * Creates a new set of collect support data task properties set from the
265   * provided task instance.
266   *
267   * @param  task  The collect support data task instance from which the
268   *               properties should be set.
269   */
270  public CollectSupportDataTaskProperties(
271              @NotNull final CollectSupportDataTask task)
272  {
273    alertOnError = task.getAlertOnError();
274    alertOnStart = task.getAlertOnStart();
275    alertOnSuccess = task.getAlertOnSuccess();
276    includeBinaryFiles = task.getIncludeBinaryFiles();
277    includeExpensiveData = task.getIncludeExpensiveData();
278    includeExtensionSource = task.getIncludeExtensionSource();
279    includeReplicationStateDump = task.getIncludeReplicationStateDump();
280    useSequentialMode = task.getUseSequentialMode();
281    securityLevel = task.getSecurityLevel();
282    scheduledStartTime = task.getScheduledStartTime();
283    failedDependencyAction = task.getFailedDependencyAction();
284    jstackCount = task.getJStackCount();
285    logFileHeadCollectionSizeKB = task.getLogFileHeadCollectionSizeKB();
286    logFileTailCollectionSizeKB = task.getLogFileTailCollectionSizeKB();
287    reportCount = task.getReportCount();
288    reportIntervalSeconds = task.getReportIntervalSeconds();
289    retainPreviousSupportDataArchiveCount =
290         task.getRetainPreviousSupportDataArchiveCount();
291    dependencyIDs = new ArrayList<>(task.getDependencyIDs());
292    notifyOnCompletion = new ArrayList<>(task.getNotifyOnCompletionAddresses());
293    notifyOnError = new ArrayList<>(task.getNotifyOnErrorAddresses());
294    notifyOnStart = new ArrayList<>(task.getNotifyOnStartAddresses());
295    notifyOnSuccess = new ArrayList<>(task.getNotifyOnSuccessAddresses());
296    comment = task.getComment();
297    encryptionPassphraseFile = task.getEncryptionPassphraseFile();
298    logDuration = task.getLogDuration();
299    outputPath = task.getOutputPath();
300    retainPreviousSupportDataArchiveAge =
301         task.getRetainPreviousSupportDataArchiveAge();
302    taskID = task.getTaskID();
303  }
304
305
306
307  /**
308   * Retrieves the path on the server filesystem to which the support data
309   * archive should be written.
310   *
311   * @return  The path on the server filesystem to which the support data
312   *          archive should be written, or {@code null} if no value has been
313   *          specified for the property.
314   */
315  @Nullable()
316  public String getOutputPath()
317  {
318    return outputPath;
319  }
320
321
322
323  /**
324   * Specifies the path on the server filesystem to which the support data '
325   * archive should be written.  If this is provided, then the value may be
326   * one of the following:
327   * <UL>
328   *   <LI>If the path refers to a file that exists, then the file will be
329   *       overwritten with the new support data archive.</LI>
330   *   <LI>If the path refers to a directory that exists, then the support data
331   *       archive will be written into that directory with a name generated
332   *       by the server.</LI>
333   *   <LI>If the path refers to a file that does not exist, then its parent
334   *       directory must exist, and the support data archive will be written
335   *       with the specified path and name.</LI>
336   * </UL>
337   *
338   * @param  outputPath  The path on the server filesystem to which the support
339   *                     data archive should be written.  It may be {@code null}
340   *                     if the server should choose the path and name for the
341   *                     output file.
342   */
343  public void setOutputPath(@Nullable final String outputPath)
344  {
345    this.outputPath = outputPath;
346  }
347
348
349
350  /**
351   * Retrieves the path on the server filesystem to a file that contains the
352   * passphrase to use to encrypt the support data archive.
353   *
354   * @return  The path on the server filesystem to a file that contains the
355   *          passphrase to use to encrypt the support data archive, or
356   *          {@code null} if no value has been specified for the property, and
357   *          the support data archive should not be encrypted.
358   */
359  @Nullable()
360  public String getEncryptionPassphraseFile()
361  {
362    return encryptionPassphraseFile;
363  }
364
365
366
367  /**
368   * Specifies the path on the server filesystem to a file that contains the
369   * passphrase to use to encrypt the support data archive.  If this is
370   * provided, then this must refer to a file that exists and that contains
371   * exactly one line whose entire content is the desired encryption passphrase.
372   *
373   * @param  encryptionPassphraseFile  The path on the server filesystem to a
374   *                                   file that contains the passphrase to use
375   *                                   to encrypt the support data archive.  It
376   *                                   may be {@code null} if the support data
377   *                                   archive should not be encrypted.
378   */
379  public void setEncryptionPassphraseFile(
380                   @Nullable final String encryptionPassphraseFile)
381  {
382    this.encryptionPassphraseFile = encryptionPassphraseFile;
383  }
384
385
386
387  /**
388   * Retrieves the value of a flag that indicates whether the support data
389   * archive may include data that is potentially expensive to collect and
390   * could affect the performance or responsiveness of the server.
391   *
392   * @return  The value of a flag that indicates whether the support data
393   *          archive may include data that is potentially expensive to collect,
394   *          or {@code null} if the property should not be specified when the
395   *          task is created (in which case the server will use a default
396   *          behavior of excluding expensive data).
397   */
398  @Nullable()
399  public Boolean getIncludeExpensiveData()
400  {
401    return includeExpensiveData;
402  }
403
404
405
406  /**
407   * Specifies the value of a flag that indicates whether the support data
408   * archive may include data that is potentially expensive to collect and could
409   * affect the performance or responsiveness of the server.
410   *
411   * @param  includeExpensiveData  The value of a flag that indicates whether
412   *                               the support data archive may include data
413   *                               that is potentially expensive to collect.  It
414   *                               may be {@code null} if the flag should not be
415   *                               specified when the task is created (in which
416   *                               case the server will use a default behavior
417   *                               of excluding expensive data).
418   */
419  public void setIncludeExpensiveData(
420                   @Nullable final Boolean includeExpensiveData)
421  {
422    this.includeExpensiveData = includeExpensiveData;
423  }
424
425
426
427  /**
428   * Retrieves the value of a flag that indicates whether the support data
429   * archive may include a replication state dump, which may be several
430   * megabytes in size.
431   *
432   * @return  The value of a flag that indicates whether the support data
433   *          archive may include a replication state dump, or {@code null} if
434   *          the property should not be specified when the task is created (in
435   *          which case the server will use a default behavior of excluding the
436   *          state dump).
437   */
438  @Nullable()
439  public Boolean getIncludeReplicationStateDump()
440  {
441    return includeReplicationStateDump;
442  }
443
444
445
446  /**
447   * Specifies the value of a flag that indicates whether the support data
448   * archive may include a replication state dump, which may be several
449   * megabytes in size.
450   *
451   * @param  includeReplicationStateDump  The value of a flag that indicates
452   *                                      whether the support data archive may
453   *                                      include a replication state dump.  It
454   *                                      may be {@code null} if the flag should
455   *                                      not be specified when the task is
456   *                                      created (in which case the server will
457   *                                      use a default behavior of excluding
458   *                                      the state dump).
459   */
460  public void setIncludeReplicationStateDump(
461                   @Nullable final Boolean includeReplicationStateDump)
462  {
463    this.includeReplicationStateDump = includeReplicationStateDump;
464  }
465
466
467
468  /**
469   * Retrieves the value of a flag that indicates whether the support data
470   * archive may include binary files.
471   *
472   * @return  The value of a flag that indicates whether the support data
473   *          archive may include binary files, or {@code null} if the property
474   *          should not be specified when the task is created (in which case
475   *          the server will use a default behavior of excluding binary files).
476   */
477  @Nullable()
478  public Boolean getIncludeBinaryFiles()
479  {
480    return includeBinaryFiles;
481  }
482
483
484
485  /**
486   * Specifies the value of a flag that that indicates whether the support data
487   * archive may include binary files.
488   *
489   * @param  includeBinaryFiles  The value of a flag that indicates whether the
490   *                             support data archive may include binary files.
491   *                             It may be {@code null} if the property should
492   *                             not be specified when the task is created (in
493   *                             which case the server will use a default
494   *                             behavior of excluding binary files).
495   */
496  public void setIncludeBinaryFiles(@Nullable final Boolean includeBinaryFiles)
497  {
498    this.includeBinaryFiles = includeBinaryFiles;
499  }
500
501
502
503  /**
504   * Retrieves the value of a flag that indicates whether the support data
505   * archive should include source code (if available) for any third-party
506   * extensions installed in the server.
507   *
508   * @return  The value of a flag that indicates whether the support data
509   *          archive should include source code (if available) for any
510   *          third-party extensions installed in the server, or {@code null} if
511   *          the property should not be specified when the task is created (in
512   *          which case the server will use a default behavior of excluding
513   *          extension source code).
514   */
515  @Nullable()
516  public Boolean getIncludeExtensionSource()
517  {
518    return includeExtensionSource;
519  }
520
521
522
523  /**
524   * Specifies the value of a flag that indicates whether the support data
525   * archive should include source code (if available) for any third-party
526   * extensions installed in the server.
527   *
528   * @param  includeExtensionSource  The value of a flag that indicates whether
529   *                                 the support data archive should include
530   *                                 source code (if available) for any
531   *                                 third-party extensions in the server.  It
532   *                                 may be {@code null} if the property should
533   *                                 not be specified when the task is
534   *                                 created (in which case the server will use
535   *                                 a default behavior of excluding extension
536   *                                 source code).
537   */
538  public void setIncludeExtensionSource(
539                   @Nullable final Boolean includeExtensionSource)
540  {
541    this.includeExtensionSource = includeExtensionSource;
542  }
543
544
545
546  /**
547   * Retrieves the value of a flag that indicates whether the server should
548   * collect items for the support data archive in sequential mode rather than
549   * in parallel.  Collecting data in sequential mode may reduce the amount of
550   * memory consumed during the collection process, but it will take longer to
551   * complete.
552   *
553   * @return  The value of a flag that indicates whether the server should
554   *          collect items for the support data archive in sequential mode
555   *          rather than in parallel, or {@code null} if the property should
556   *          not be specified when the task is created (in which case the
557   *          server will default to capturing data in parallel).
558   */
559  @Nullable()
560  public Boolean getUseSequentialMode()
561  {
562    return useSequentialMode;
563  }
564
565
566
567  /**
568   * Specifies the value of a flag that indicates whether the server should
569   * collect items for the support data archive in sequential mode rather than
570   * in parallel.  Collecting data in sequential mode may reduce the amount of
571   * memory consumed during the collection process, but it will take longer to
572   * complete.
573   *
574   * @param  useSequentialMode  The value of a flag that indicates whether the
575   *                            server should collect items for the support data
576   *                            archive in sequential mode rather than in
577   *                            parallel.  It may be {@code null} if the
578   *                            property should not be specified when the task
579   *                            is created (in which case the server will
580   *                            default to capturing data in parallel).
581   */
582  public void setUseSequentialMode(@Nullable final Boolean useSequentialMode)
583  {
584    this.useSequentialMode = useSequentialMode;
585  }
586
587
588
589  /**
590   * Retrieves the security level that should be used to indicate which data
591   * should be obscured, redacted, or omitted from the support data archive.
592   *
593   * @return  The security level that should be used when creating the support
594   *          data archive, or {@code null} if the property should not be
595   *          specified when the task is created (in which case the server will
596   *          use a default security level).
597   */
598  @Nullable()
599  public CollectSupportDataSecurityLevel getSecurityLevel()
600  {
601    return securityLevel;
602  }
603
604
605
606  /**
607   * Specifies the security level that should be used to indicate which data
608   * should be obscured, redacted, or omitted from the support data archive.
609   *
610   * @param  securityLevel  The security level that should be used when creating
611   *                        the support data archive.  It may be {@code null} if
612   *                        the property should not be specified when the task
613   *                        is created (in which case the server will use a
614   *                        default security level).
615   */
616  public void setSecurityLevel(
617       @Nullable final CollectSupportDataSecurityLevel securityLevel)
618
619  {
620    this.securityLevel = securityLevel;
621  }
622
623
624
625  /**
626   * Retrieves the number of intervals that should be captured from tools that
627   * use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.).
628   *
629   * @return  The number of intervals that should be captured from tools that
630   *          use interval-based sampling, or {@code null} if the property
631   *          should not be specified when the task is created (in which case
632   *          the server will use a default report count).
633   */
634  @Nullable()
635  public Integer getReportCount()
636  {
637    return reportCount;
638  }
639
640
641
642  /**
643   * Specifies the number of intervals that should be captured form tools that
644   * use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.).
645   *
646   * @param  reportCount  The number of intervals that should be captured from
647   *                      tools that use interval-based sampling.  The value
648   *                      must not be negative, but it may be zero to indicate
649   *                      that no intervals should be captured.  It may be
650   *                      {@code null} if the property should not be specified
651   *                      when the task is created (in which case the server
652   *                      will use a default report count).
653   */
654  public void setReportCount(@Nullable final Integer reportCount)
655  {
656    this.reportCount = reportCount;
657  }
658
659
660
661  /**
662   * Retrieves the interval duration in seconds that should be used for tools
663   * that use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.).
664   *
665   * @return  The interval duration in seconds that should be used for tools
666   *          that use interval-based sampling, or {@code null} if the property
667   *          should not be specified when the task is created (in which case
668   *          the server will use a default report interval).
669   */
670  @Nullable()
671  public Integer getReportIntervalSeconds()
672  {
673    return reportIntervalSeconds;
674  }
675
676
677
678  /**
679   * Specifies the interval duration in seconds that should be used for tools
680   * that use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.).
681   *
682   * @param  reportIntervalSeconds  The interval duration in seconds that should
683   *                                be used for tools that use interval-based
684   *                                sampling.  The value must be greater than or
685   *                                equal to one.  It may be {@code null} if the
686   *                                property should not be specified when the
687   *                                task is created (in which case the server
688   *                                will use a default report count).
689   */
690  public void setReportIntervalSeconds(
691                   @Nullable final Integer reportIntervalSeconds)
692  {
693    this.reportIntervalSeconds = reportIntervalSeconds;
694  }
695
696
697
698  /**
699   * Retrieves the number of times that the jstack utility should be invoked to
700   * obtain stack traces from all threads in the server.
701   *
702   * @return  The number of times that the jstack utility should be invoked to
703   *          obtain stack traces from all threads in the server, or
704   *          {@code null} if the property should not be specified when the task
705   *          is created (in which case the server will use a default count).
706   */
707  @Nullable()
708  public Integer getJStackCount()
709  {
710    return jstackCount;
711  }
712
713
714
715  /**
716   * Specifies the number of times that the jstack utility should be invoked to
717   * obtain stack traces from all threads in the server.
718   *
719   * @param  jstackCount  The number of times that the jstack utility should be
720   *                      invoked to obtain stack traces from all threads in the
721   *                      server.  The value must not be negative, but it may be
722   *                      zero to indicate that the jstack utility should not be
723   *                      invoked.  It may be {@code null} if the property
724   *                      should not be specified when the task is created (in
725   *                      which case the server will use a default count).
726   */
727  public void setJStackCount(@Nullable final Integer jstackCount)
728  {
729    this.jstackCount = jstackCount;
730  }
731
732
733
734  /**
735   * Retrieves a string representation of the duration (up until the time that
736   * the collect support data task is invoked) of log content that should be
737   * included in the support data archive.
738   *
739   * @return  A string representation of the duration of log content that should
740   *          be included in the support data archive, or {@code null} if the
741   *          property should not be specified when the task is created (in
742   *          which case the server will use a default behavior for selecting
743   *          the amount of log content to include).
744   */
745  @Nullable()
746  public String getLogDuration()
747  {
748    return logDuration;
749  }
750
751
752
753  /**
754   * Retrieves a parsed value of the log duration in milliseconds.
755   *
756   * @return  A parsed value of the log duration in milliseconds or {@code null}
757   *          if no log duration is set.
758   *
759   * @throws  TaskException  If the log duration value cannot be parsed as a
760   *                         valid duration.
761   */
762  @Nullable()
763  public Long getLogDurationMillis()
764         throws TaskException
765  {
766    if (logDuration == null)
767    {
768      return null;
769    }
770
771    try
772    {
773      return DurationArgument.parseDuration(logDuration, TimeUnit.MILLISECONDS);
774    }
775    catch (final ArgumentException e)
776    {
777      Debug.debugException(e);
778      throw new TaskException(e.getMessage(), e);
779    }
780  }
781
782
783
784  /**
785   * Specifies the string representation of the duration (up until the time that
786   * the collect support data task is invoked) of log content that should be
787   * included in the support data archive.
788   * <BR><BR>
789   * The string representation of the duration should be specified as
790   * an integer followed by a time unit, where the unit may be one of
791   * millisecond, second, minute, hour, day, or week (or one of their plurals).
792   * For example, "5 minutes" or "1 hour".
793   *
794   * @param  logDuration  The string representation of the duration of log
795   *                      content that should be included in the support data
796   *                      archive.  It may be {@code null} if the property
797   *                      should not be specified when the task is created (in
798   *                      which case the server will determine an appropriate
799   *                      amount of log content to include).
800   *
801   * @throws  TaskException  If the provided string representation cannot be
802   *                         parsed as a valid duration.
803   */
804  public void setLogDuration(@Nullable final String logDuration)
805         throws TaskException
806  {
807    if (logDuration == null)
808    {
809      this.logDuration = null;
810    }
811    else
812    {
813      try
814      {
815        DurationArgument.parseDuration(logDuration, TimeUnit.MILLISECONDS);
816        this.logDuration = logDuration;
817      }
818      catch (final ArgumentException e)
819      {
820        Debug.debugException(e);
821        throw new TaskException(e.getMessage(), e);
822      }
823    }
824  }
825
826
827
828  /**
829   * Specifies the duration in milliseconds (up until the time that the collect
830   * support data task is invoked) of log content that should be included in the
831   * support data archive.
832   *
833   * @param  logDurationMillis  The duration in milliseconds of log content that
834   *                            should be included in the support data archive.
835   *                            The value must be greater than zero.  It may be
836   *                            {@code null} if the property should not be
837   *                            specified when the task is created (in which
838   *                            case the server will determine an appropriate
839   *                            amount of log content to include).
840   */
841  public void setLogDurationMillis(@Nullable final Long logDurationMillis)
842  {
843    if (logDurationMillis == null)
844    {
845      logDuration = null;
846    }
847    else
848    {
849      logDuration = DurationArgument.nanosToDuration(
850           TimeUnit.MILLISECONDS.toNanos(logDurationMillis));
851    }
852  }
853
854
855
856  /**
857   * Retrieves the amount of data in kilobytes to capture from the beginning of
858   * each log file that should be included in the support data archive.
859   *
860   * @return  The amount of data in kilobytes to capture from the beginning of
861   *          each log file that should be included in the support data archive,
862   *          or {@code null} if the property should not be specified when the
863   *          task is created (in which case the server will determine an
864   *          appropriate amount of log content to include).
865   */
866  @Nullable()
867  public Integer getLogFileHeadCollectionSizeKB()
868  {
869    return logFileHeadCollectionSizeKB;
870  }
871
872
873
874  /**
875   * Specifies the amount of data in kilobytes to capture from the beginning of
876   * each log file that should be included in the support data archive.
877   *
878   * @param  logFileHeadCollectionSizeKB  The amount of data in kilobytes to
879   *                                      capture from the beginning of each log
880   *                                      file that should be included in the
881   *                                      support data archive.  This may be
882   *                                      {@code null} if the property should
883   *                                      not be specified when the task is
884   *                                      created (in which case the server will
885   *                                      determine an appropriate amount of log
886   *                                      content to include).
887   */
888  public void setLogFileHeadCollectionSizeKB(
889                   @Nullable final Integer logFileHeadCollectionSizeKB)
890  {
891    this.logFileHeadCollectionSizeKB = logFileHeadCollectionSizeKB;
892  }
893
894
895
896  /**
897   * Retrieves the amount of data in kilobytes to capture from the end of each
898   * log file that should be included in the support data archive.
899   *
900   * @return  The amount of data in kilobytes to capture from the end of each
901   *          log file that should be included in the support data archive, or
902   *          {@code null} if the property should not be specified when the task
903   *          is created (in which case the server will determine an
904   *          appropriate amount of log content to include).
905   */
906  @Nullable()
907  public Integer getLogFileTailCollectionSizeKB()
908  {
909    return logFileTailCollectionSizeKB;
910  }
911
912
913
914  /**
915   * Specifies the amount of data in kilobytes to capture from the end of each
916   * log file that should be included in the support data archive.
917   *
918   * @param  logFileTailCollectionSizeKB  The amount of data in kilobytes to
919   *                                      capture from the end of each log file
920   *                                      that should be included in the
921   *                                      support data archive.  This may be
922   *                                      {@code null} if the property should
923   *                                      not be specified when the task is
924   *                                      created (in which case the server will
925   *                                      determine an appropriate amount of log
926   *                                      content to include).
927   */
928  public void setLogFileTailCollectionSizeKB(
929                   @Nullable final Integer logFileTailCollectionSizeKB)
930  {
931    this.logFileTailCollectionSizeKB = logFileTailCollectionSizeKB;
932  }
933
934
935
936  /**
937   * Retrieves an additional comment that should be included in the support data
938   * archive.
939   *
940   * @return  An additional comment that should be included in the support data
941   *          archive, or {@code null} if no comment should be included.
942   */
943  @Nullable()
944  public String getComment()
945  {
946    return comment;
947  }
948
949
950
951  /**
952   * Specifies an additional comment that should be included in the support data
953   * archive.
954   *
955   * @param  comment  An additional comment that should be included in the
956   *                  support data archive.  It may be {@code null} if no
957   *                  additional comment should be included.
958   */
959  public void setComment(@Nullable final String comment)
960  {
961    this.comment = comment;
962  }
963
964
965
966  /**
967   * Retrieves the minimum number of existing support data archives that should
968   * be retained.
969   *
970   * @return  The minimum number of existing support data archives that should
971   *          be retained, or {@code null} if there is no minimum retain count.
972   */
973  @Nullable()
974  public Integer getRetainPreviousSupportDataArchiveCount()
975  {
976    return retainPreviousSupportDataArchiveCount;
977  }
978
979
980
981  /**
982   * Specifies the minimum number of existing support data archives that should
983   * be retained.
984   * <BR><BR>
985   * Note that if an output path is specified, then a retain count or retain age
986   * may only be used if that output path specifies a directory rather than a
987   * file, so that the file name will be generated by the server, and only
988   * archive files in that directory with names that conform to the
989   * server-generated pattern may be removed.
990   * <BR><BR>
991   * If neither a retain count nor a retain age is specified, then no existing
992   * support data archives will be removed.  If both are specified, then any
993   * existing archive that is outside the criteria for either will be removed.
994   *
995   * @param  retainPreviousSupportDataArchiveCount
996   *              The minimum number of existing support data archives that
997   *              should be retained.  A value of zero indicates that only the
998   *              new support data archive should be retained, and any other
999   *              preexisting archives may be removed.  It may be {@code null}
1000   *              if only the age of existing archives should be considered (if
1001   *              a retain age is specified), or if no existing support data
1002   *              archives should be removed (if no retain age is specified).
1003   */
1004  public void setRetainPreviousSupportDataArchiveCount(
1005       @Nullable final Integer retainPreviousSupportDataArchiveCount)
1006  {
1007    this.retainPreviousSupportDataArchiveCount =
1008         retainPreviousSupportDataArchiveCount;
1009  }
1010
1011
1012
1013  /**
1014   * Retrieves the minimum age of existing support data archives that should be
1015   * retained.
1016   *
1017   * @return  The minimum age of existing support data archives that should
1018   *          be retained, or {@code null} if there is no minimum retain age.
1019   */
1020  @Nullable()
1021  public String getRetainPreviousSupportDataArchiveAge()
1022  {
1023    return retainPreviousSupportDataArchiveAge;
1024  }
1025
1026
1027
1028  /**
1029   * Retrieves a parsed value of the retain previous support data archive age in
1030   * milliseconds.
1031   *
1032   * @return  A parsed value of the retain previous support data archive age in
1033   *          milliseconds or {@code null} if no retain age is set.
1034   *
1035   * @throws  TaskException  If the retain age value cannot be parsed as a valid
1036   *                         duration.
1037   */
1038  @Nullable()
1039  public Long getRetainPreviousSupportDataArchiveAgeMillis()
1040         throws TaskException
1041  {
1042    if (retainPreviousSupportDataArchiveAge == null)
1043    {
1044      return null;
1045    }
1046
1047    try
1048    {
1049      return DurationArgument.parseDuration(
1050           retainPreviousSupportDataArchiveAge, TimeUnit.MILLISECONDS);
1051    }
1052    catch (final ArgumentException e)
1053    {
1054      Debug.debugException(e);
1055      throw new TaskException(e.getMessage(), e);
1056    }
1057  }
1058
1059
1060
1061  /**
1062   * Specifies the minimum age of existing support data archives that should be
1063   * retained.
1064   * <BR><BR>
1065   * The string representation of the duration should be specified as an integer
1066   * followed by a time unit, where the unit may be one of millisecond, second,
1067   * minute, hour, day, or week (or one of their plurals).  For example, "5
1068   * minutes" or "1 hour".
1069   * <BR><BR>
1070   * Note that if an output path is specified, then a retain count or retain age
1071   * may only be used if that output path specifies a directory rather than a
1072   * file, so that the file name will be generated by the server, and only
1073   * archive files in that directory with names that conform to the
1074   * server-generated pattern may be removed.
1075   * <BR><BR>
1076   * If neither a retain count nor a retain age is specified, then no existing
1077   * support data archives will be removed.  If both are specified, then any
1078   * existing archive that is outside the criteria for either will be removed.
1079   *
1080   * @param  retainPreviousSupportDataArchiveAge
1081   *              The minimum age of existing support data archives that
1082   *              should be retained.  Any existing support data archives that
1083   *              are older than this may be removed.  It may be {@code null}
1084   *              if only the number of existing archives should be considered
1085   *              (if a retain count is specified), or if no existing support
1086   *              data archives should be removed (if no retain count is
1087   *              specified).
1088   *
1089   * @throws  TaskException  If the provided string representation cannot be
1090   *                         parsed as a valid duration.
1091   */
1092  public void setRetainPreviousSupportDataArchiveAge(
1093                   @Nullable final String retainPreviousSupportDataArchiveAge)
1094         throws TaskException
1095  {
1096    if (retainPreviousSupportDataArchiveAge == null)
1097    {
1098      this.retainPreviousSupportDataArchiveAge = null;
1099    }
1100    else
1101    {
1102      try
1103      {
1104        DurationArgument.parseDuration(retainPreviousSupportDataArchiveAge,
1105             TimeUnit.MILLISECONDS);
1106        this.retainPreviousSupportDataArchiveAge =
1107             retainPreviousSupportDataArchiveAge;
1108      }
1109      catch (final ArgumentException e)
1110      {
1111        Debug.debugException(e);
1112        throw new TaskException(e.getMessage(), e);
1113      }
1114    }
1115  }
1116
1117
1118
1119  /**
1120   * Specifies the minimum age in milliseconds of existing support data
1121   * archives that should be retained.
1122   * <BR><BR>
1123   * Note that if an output path is specified, then a retain count or retain age
1124   * may only be used if that output path specifies a directory rather than a
1125   * file, so that the file name will be generated by the server, and only
1126   * archive files in that directory with names that conform to the
1127   * server-generated pattern may be removed.
1128   * <BR><BR>
1129   * If neither a retain count nor a retain age is specified, then no existing
1130   * support data archives will be removed.  If both are specified, then any
1131   * existing archive that is outside the criteria for either will be removed.
1132   *
1133   * @param  retainPreviousSupportDataArchiveAgeMillis
1134   *              The minimum age in milliseconds of existing support data
1135   *              archives that should be retained.  Any existing support data
1136   *              archives that are older than this may be removed.  It may be
1137   *              {@code null} if only the number of existing archives should be
1138   *              considered (if a retain count is specified), or if no existing
1139   *              support data archives should be removed (if no retain count is
1140   *              specified).
1141   */
1142  public void setRetainPreviousSupportDataArchiveAgeMillis(
1143       @Nullable final Long retainPreviousSupportDataArchiveAgeMillis)
1144  {
1145    if (retainPreviousSupportDataArchiveAgeMillis == null)
1146    {
1147      retainPreviousSupportDataArchiveAge = null;
1148    }
1149    else
1150    {
1151      retainPreviousSupportDataArchiveAge = DurationArgument.nanosToDuration(
1152           TimeUnit.MILLISECONDS.toNanos(
1153                retainPreviousSupportDataArchiveAgeMillis));
1154    }
1155  }
1156
1157
1158
1159  /**
1160   * Retrieves the task ID that should be used for the task.
1161   *
1162   * @return  The task ID that should be used for the task, or {@code null} if a
1163   *          random UUID should be generated for use as the task ID.
1164   */
1165  @Nullable()
1166  public String getTaskID()
1167  {
1168    return taskID;
1169  }
1170
1171
1172
1173  /**
1174   *Specifies the task ID that should be used for the task.
1175   *
1176   * @param  taskID  The task ID that should be used for the task.  It may be
1177   *                 {@code null} if a random UUID should be generated for use
1178   *                 as the task ID.
1179   */
1180  public void setTaskID(@Nullable final String taskID)
1181  {
1182    this.taskID = taskID;
1183  }
1184
1185
1186
1187  /**
1188   * Retrieves the earliest time that the task should be eligible to start
1189   * running.
1190   *
1191   * @return  The earliest time that the task should be eligible to start
1192   *          running, or {@code null} if the task should be eligible to start
1193   *          immediately (or as soon as all of its dependencies have been
1194   *          satisfied).
1195   */
1196  @Nullable()
1197  public Date getScheduledStartTime()
1198  {
1199    return scheduledStartTime;
1200  }
1201
1202
1203
1204  /**
1205   * Specifies the earliest time that the task should be eligible to start
1206   * running.
1207   *
1208   * @param  scheduledStartTime  The earliest time that the task should be
1209   *                             eligible to start running.  It may be
1210   *                             {@code null} if the task should be eligible to
1211   *                             start immediately (or as soon as all of its
1212   *                             dependencies have been satisfied).
1213   */
1214  public void setScheduledStartTime(@Nullable final Date scheduledStartTime)
1215  {
1216    this.scheduledStartTime = scheduledStartTime;
1217  }
1218
1219
1220
1221  /**
1222   * Retrieves the task IDs for any tasks that must complete before the new
1223   * collect support data task will be eligible to start running.
1224   *
1225   * @return  The task IDs for any tasks that must complete before the new
1226   *          collect support data task will be eligible to start running, or
1227   *          an empty list if the new task should not depend on any other
1228   *          tasks.
1229   */
1230  @NotNull()
1231  public List<String> getDependencyIDs()
1232  {
1233    return new ArrayList<>(dependencyIDs);
1234  }
1235
1236
1237
1238  /**
1239   * Specifies the task IDs for any tasks that must complete before the new
1240   * collect support data task will be eligible to start running.
1241   *
1242   * @param  dependencyIDs  The task IDs for any tasks that must complete before
1243   *                        the new collect support data task will be eligible
1244   *                        to start running.  It may be {@code null} or empty
1245   *                        if the new task should not depend on any other
1246   *                        tasks.
1247   */
1248  public void setDependencyIDs(@Nullable final List<String> dependencyIDs)
1249  {
1250    this.dependencyIDs.clear();
1251    if (dependencyIDs != null)
1252    {
1253      this.dependencyIDs.addAll(dependencyIDs);
1254    }
1255  }
1256
1257
1258
1259  /**
1260   * Retrieves the action that the server should take if any of the tasks on
1261   * which the new task depends did not complete successfully.
1262   *
1263   * @return  The action that the server should take if any of the tasks on
1264   *          which the new task depends did not complete successfully, or
1265   *          {@code null} if the property should not be specified when creating
1266   *          the task (and the server should choose an appropriate failed
1267   *          dependency action).
1268   */
1269  @Nullable()
1270  public FailedDependencyAction getFailedDependencyAction()
1271  {
1272    return failedDependencyAction;
1273  }
1274
1275
1276
1277  /**
1278   * Specifies the action that the server should take if any of the tasks on
1279   * which the new task depends did not complete successfully.
1280   *
1281   * @param  failedDependencyAction  The action that the server should take if
1282   *                                 any of the tasks on which the new task
1283   *                                 depends did not complete successfully.  It
1284   *                                 may be {@code null} if the property should
1285   *                                 not be specified when creating the task
1286   *                                 (and the server should choose an
1287   *                                 appropriate failed dependency action).
1288   */
1289  public void setFailedDependencyAction(
1290       @Nullable final FailedDependencyAction failedDependencyAction)
1291  {
1292    this.failedDependencyAction = failedDependencyAction;
1293  }
1294
1295
1296
1297  /**
1298   * Retrieves the addresses to email whenever the task starts running.
1299   *
1300   * @return  The addresses to email whenever the task starts running, or an
1301   *          empty list if no email notification should be sent when starting
1302   *          the task.
1303   */
1304  @NotNull()
1305  public List<String> getNotifyOnStart()
1306  {
1307    return new ArrayList<>(notifyOnStart);
1308  }
1309
1310
1311
1312  /**
1313   * Specifies the addresses to email whenever the task starts running.
1314   *
1315   * @param  notifyOnStart  The addresses to email whenever the task starts
1316   *                        running.  It amy be {@code null} or empty if no
1317   *                        email notification should be sent when starting the
1318   *                        task.
1319   */
1320  public void setNotifyOnStart(@Nullable final List<String> notifyOnStart)
1321  {
1322    this.notifyOnStart.clear();
1323    if (notifyOnStart != null)
1324    {
1325      this.notifyOnStart.addAll(notifyOnStart);
1326    }
1327  }
1328
1329
1330
1331  /**
1332   * Retrieves the addresses to email whenever the task completes, regardless of
1333   * its success or failure.
1334   *
1335   * @return  The addresses to email whenever the task completes, or an
1336   *          empty list if no email notification should be sent when the task
1337   *          completes.
1338   */
1339  @NotNull()
1340  public List<String> getNotifyOnCompletion()
1341  {
1342    return new ArrayList<>(notifyOnCompletion);
1343  }
1344
1345
1346
1347  /**
1348   * Specifies the addresses to email whenever the task completes, regardless of
1349   * its success or failure.
1350   *
1351   * @param  notifyOnCompletion  The addresses to email whenever the task
1352   *                             completes.  It amy be {@code null} or empty if
1353   *                             no email notification should be sent when the
1354   *                             task completes.
1355   */
1356  public void setNotifyOnCompletion(
1357                   @Nullable final List<String> notifyOnCompletion)
1358  {
1359    this.notifyOnCompletion.clear();
1360    if (notifyOnCompletion != null)
1361    {
1362      this.notifyOnCompletion.addAll(notifyOnCompletion);
1363    }
1364  }
1365
1366
1367
1368  /**
1369   * Retrieves the addresses to email if the task completes successfully.
1370   *
1371   * @return  The addresses to email if the task completes successfully, or an
1372   *          empty list if no email notification should be sent on successful
1373   *          completion.
1374   */
1375  @NotNull()
1376  public List<String> getNotifyOnSuccess()
1377  {
1378    return new ArrayList<>(notifyOnSuccess);
1379  }
1380
1381
1382
1383  /**
1384   * Specifies the addresses to email if the task completes successfully.
1385   *
1386   * @param  notifyOnSuccess  The addresses to email if the task completes
1387   *                          successfully.  It amy be {@code null} or empty if
1388   *                          no email notification should be sent on
1389   *                          successful completion.
1390   */
1391  public void setNotifyOnSuccess(@Nullable final List<String> notifyOnSuccess)
1392  {
1393    this.notifyOnSuccess.clear();
1394    if (notifyOnSuccess != null)
1395    {
1396      this.notifyOnSuccess.addAll(notifyOnSuccess);
1397    }
1398  }
1399
1400
1401
1402  /**
1403   * Retrieves the addresses to email if the task does not complete
1404   * successfully.
1405   *
1406   * @return  The addresses to email if the task does not complete successfully,
1407   *          or an empty list if no email notification should be sent on an
1408   *          unsuccessful completion.
1409   */
1410  @NotNull()
1411  public List<String> getNotifyOnError()
1412  {
1413    return new ArrayList<>(notifyOnError);
1414  }
1415
1416
1417
1418  /**
1419   * Specifies the addresses to email if the task does not complete
1420   * successfully.
1421   *
1422   * @param  notifyOnError  The addresses to email if the task does not complete
1423   *                        successfully.  It amy be {@code null} or empty if
1424   *                        no email notification should be sent on an
1425   *                        unsuccessful completion.
1426   */
1427  public void setNotifyOnError(@Nullable final List<String> notifyOnError)
1428  {
1429    this.notifyOnError.clear();
1430    if (notifyOnError != null)
1431    {
1432      this.notifyOnError.addAll(notifyOnError);
1433    }
1434  }
1435
1436
1437
1438  /**
1439   * Retrieves the flag that indicates whether the server should send an
1440   * administrative alert notification when the task starts running.
1441   *
1442   * @return  The flag that indicates whether the server should send an
1443   *          administrative alert notification when the task starts running,
1444   *          or {@code null} if the property should not be specified when the
1445   *          task is created (and the server will default to not sending any
1446   *          alert).
1447   */
1448  @Nullable()
1449  public Boolean getAlertOnStart()
1450  {
1451    return alertOnStart;
1452  }
1453
1454
1455
1456  /**
1457   * Specifies the flag that indicates whether the server should send an
1458   * administrative alert notification when the task starts running.
1459   *
1460   * @param  alertOnStart  The flag that indicates whether the server should
1461   *                       send an administrative alert notification when the
1462   *                       task starts running,  It may be {@code null} if the
1463   *                       property should not be specified when the task is
1464   *                       created (and the server will default to not sending
1465   *                       any alert).
1466   */
1467  public void setAlertOnStart(@Nullable final Boolean alertOnStart)
1468  {
1469    this.alertOnStart = alertOnStart;
1470  }
1471
1472
1473
1474  /**
1475   * Retrieves the flag that indicates whether the server should send an
1476   * administrative alert notification if the task completes successfully.
1477   *
1478   * @return  The flag that indicates whether the server should send an
1479   *          administrative alert notification if the task completes
1480   *          successfully, or {@code null} if the property should not be
1481   *          specified when the task is created (and the server will default to
1482   *          not sending any alert).
1483   */
1484  @Nullable()
1485  public Boolean getAlertOnSuccess()
1486  {
1487    return alertOnSuccess;
1488  }
1489
1490
1491
1492  /**
1493   * Specifies the flag that indicates whether the server should send an
1494   * administrative alert notification if the task completes successfully.
1495   *
1496   * @param  alertOnSuccess  The flag that indicates whether the server should
1497   *                         send an administrative alert notification if the
1498   *                         task completes successfully,  It may be
1499   *                         {@code null} if the property should not be
1500   *                         specified when the task is created (and the server
1501   *                         will default to not sending any alert).
1502   */
1503  public void setAlertOnSuccess(@Nullable final Boolean alertOnSuccess)
1504  {
1505    this.alertOnSuccess = alertOnSuccess;
1506  }
1507
1508
1509
1510  /**
1511   * Retrieves the flag that indicates whether the server should send an
1512   * administrative alert notification if the task does not complete
1513   * successfully.
1514   *
1515   * @return  The flag that indicates whether the server should send an
1516   *          administrative alert notification if the task does not complete
1517   *          successfully, or {@code null} if the property should not be
1518   *          specified when the task is created (and the server will default to
1519   *          not sending any alert).
1520   */
1521  @Nullable()
1522  public Boolean getAlertOnError()
1523  {
1524    return alertOnError;
1525  }
1526
1527
1528
1529  /**
1530   * Specifies the flag that indicates whether the server should send an
1531   * administrative alert notification if the task does not complete
1532   * successfully.
1533   *
1534   * @param  alertOnError  The flag that indicates whether the server should
1535   *                       send an administrative alert notification if the task
1536   *                       does not complete successfully,  It may be
1537   *                       {@code null} if the property should not be specified
1538   *                       when the task is created (and the server will default
1539   *                       to not sending any alert).
1540   */
1541  public void setAlertOnError(@Nullable final Boolean alertOnError)
1542  {
1543    this.alertOnError = alertOnError;
1544  }
1545
1546
1547
1548  /**
1549   * Retrieves a string representation of this collect support data task
1550   * properties object.
1551   *
1552   * @return  A string representation of this collect support data task
1553   *          properties object.
1554   */
1555  @Override()
1556  @NotNull()
1557  public String toString()
1558  {
1559    final StringBuilder buffer = new StringBuilder();
1560    toString(buffer);
1561    return buffer.toString();
1562  }
1563
1564
1565
1566  /**
1567   * Appends a string representation of this collect support data task
1568   * properties object to the provided buffer.
1569   *
1570   * @param  buffer  The buffer to which the string representation will be
1571   *                 appended.  It must not be {@code null}.
1572   */
1573  public void toString(@NotNull final StringBuilder buffer)
1574  {
1575    buffer.append("CollectSupportDataArchiveProperties(");
1576
1577    appendNameValuePair(buffer, "taskID", taskID);
1578    appendNameValuePair(buffer, "outputPath", outputPath);
1579    appendNameValuePair(buffer, "encryptionPassphraseFile",
1580         encryptionPassphraseFile);
1581    appendNameValuePair(buffer, "includeExpensiveData", includeExpensiveData);
1582    appendNameValuePair(buffer, "includeReplicationStateDump",
1583         includeReplicationStateDump);
1584    appendNameValuePair(buffer, "includeBinaryFiles", includeBinaryFiles);
1585    appendNameValuePair(buffer, "includeExtensionSource",
1586         includeExtensionSource);
1587    appendNameValuePair(buffer, "securityLevel", securityLevel);
1588    appendNameValuePair(buffer, "useSequentialMode", useSequentialMode);
1589    appendNameValuePair(buffer, "reportCount", reportCount);
1590    appendNameValuePair(buffer, "reportIntervalSeconds", reportIntervalSeconds);
1591    appendNameValuePair(buffer, "jstackCount", jstackCount);
1592    appendNameValuePair(buffer, "logDuration", logDuration);
1593    appendNameValuePair(buffer, "logFileHeadCollectionSizeKB",
1594         logFileHeadCollectionSizeKB);
1595    appendNameValuePair(buffer, "logFileTailCollectionSizeKB",
1596         logFileTailCollectionSizeKB);
1597    appendNameValuePair(buffer, "comment", comment);
1598    appendNameValuePair(buffer, "retainPreviousSupportDataArchiveCount",
1599         retainPreviousSupportDataArchiveCount);
1600    appendNameValuePair(buffer, "retainPreviousSupportDataArchiveAge",
1601         retainPreviousSupportDataArchiveAge);
1602    appendNameValuePair(buffer, "scheduledStartTime", scheduledStartTime);
1603    appendNameValuePair(buffer, "dependencyIDs", dependencyIDs);
1604    appendNameValuePair(buffer, "failedDependencyAction",
1605         failedDependencyAction);
1606    appendNameValuePair(buffer, "notifyOnStart", notifyOnStart);
1607    appendNameValuePair(buffer, "notifyOnCompletion", notifyOnCompletion);
1608    appendNameValuePair(buffer, "notifyOnSuccess", notifyOnSuccess);
1609    appendNameValuePair(buffer, "notifyOnError", notifyOnError);
1610    appendNameValuePair(buffer, "alertOnStart", alertOnStart);
1611    appendNameValuePair(buffer, "alertOnSuccess", alertOnSuccess);
1612    appendNameValuePair(buffer, "alertOnError", alertOnError);
1613
1614    buffer.append(')');
1615  }
1616
1617
1618
1619  /**
1620   * Appends a name-value pair to the provided buffer, if the value is
1621   * non-{@code null}.
1622   *
1623   * @param  buffer  The buffer to which the name-value pair should be appended.
1624   * @param  name    The name to be used.  It must not be {@code null}.
1625   * @param  value   The value to be used.  It may be {@code null} if there is
1626   *                 no value for the property.
1627   */
1628  private static void appendNameValuePair(@NotNull final StringBuilder buffer,
1629                                          @NotNull final String name,
1630                                          @Nullable final Object value)
1631  {
1632    if (value == null)
1633    {
1634      return;
1635    }
1636
1637    if ((buffer.length() > 0) &&
1638         (buffer.charAt(buffer.length() - 1) != '('))
1639    {
1640      buffer.append(", ");
1641    }
1642
1643    buffer.append(name);
1644    buffer.append("='");
1645    buffer.append(value);
1646    buffer.append('\'');
1647  }
1648
1649
1650
1651  /**
1652   * Appends a name-value pair to the provided buffer, if the value is
1653   * non-{@code null}.
1654   *
1655   * @param  buffer   The buffer to which the name-value pair should be
1656   *                  appended.
1657   * @param  name     The name to be used.  It must not be {@code null}.
1658   * @param  values   The list of values to be used.  It may be {@code null} or
1659   *                  empty if there are no values for the property.
1660   */
1661  private static void appendNameValuePair(@NotNull final StringBuilder buffer,
1662                                          @NotNull final String name,
1663                                          @Nullable final List<String> values)
1664  {
1665    if ((values == null) || values.isEmpty())
1666    {
1667      return;
1668    }
1669
1670    if ((buffer.length() > 0) &&
1671         (buffer.charAt(buffer.length() - 1) != '('))
1672    {
1673      buffer.append(", ");
1674    }
1675
1676    buffer.append(name);
1677    buffer.append("={ ");
1678
1679    final Iterator<String> iterator = values.iterator();
1680    while (iterator.hasNext())
1681    {
1682      buffer.append('\'');
1683      buffer.append(iterator.next());
1684      buffer.append('\'');
1685
1686      if (iterator.hasNext())
1687      {
1688        buffer.append(", ");
1689      }
1690    }
1691
1692    buffer.append('}');
1693  }
1694}