001/*
002 * Copyright 2008-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2018 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk.unboundidds.tasks;
022
023
024
025import java.util.ArrayList;
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.Date;
029import java.util.LinkedHashMap;
030import java.util.List;
031import java.util.Map;
032
033import com.unboundid.ldap.sdk.Attribute;
034import com.unboundid.ldap.sdk.Entry;
035import com.unboundid.util.NotMutable;
036import com.unboundid.util.StaticUtils;
037import com.unboundid.util.ThreadSafety;
038import com.unboundid.util.ThreadSafetyLevel;
039import com.unboundid.util.Validator;
040import com.unboundid.util.args.DurationArgument;
041
042import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*;
043
044
045
046/**
047 * This class defines a Directory Server task that can be used to back up one or
048 * more Directory Server backends.
049 * <BR>
050 * <BLOCKQUOTE>
051 *   <B>NOTE:</B>  This class, and other classes within the
052 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
053 *   supported for use against Ping Identity, UnboundID, and
054 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
055 *   for proprietary functionality or for external specifications that are not
056 *   considered stable or mature enough to be guaranteed to work in an
057 *   interoperable way with other types of LDAP servers.
058 * </BLOCKQUOTE>
059 * <BR>
060 * The properties that are available for use with this type of task include:
061 * <UL>
062 *   <LI>The path to the directory in which the backup should be placed.  If
063 *       multiple backends are to be backed up at once, then this should be the
064 *       parent of the backup directories for each backend.  This must be
065 *       provided when scheduling this task.</LI>
066 *   <LI>The backend IDs of the backends to archive.  If this is not provided,
067 *       then the server will attempt to back up all supported backends.</LI>
068 *   <LI>The backup ID to use for the backup.  If this is not provided, then the
069 *       server will generate a backup ID.</LI>
070 *   <LI>A flag that indicates whether the backup should be an incremental
071 *       backup (if the backend supports that capability) or a full backup.</LI>
072 *   <LI>The backup ID of the existing backup on which the incremental backup
073 *       should be based.  If this is not provided and an incremental backup
074 *       is to be performed, then it will be based on the most recent backup in
075 *       the backup directory.</LI>
076 *   <LI>A flag that indicates whether to compress the contents of the
077 *       backup.</LI>
078 *   <LI>A flag that indicates whether to encrypt the contents of the
079 *       backup.</LI>
080 *   <LI>A flag that indicates whether to hash the contents of the backup to use
081 *       as a checksum for verifying the integrity of the backup.</LI>
082 *   <LI>A flag that indicates whether to sign the backup hash in order to
083 *       prevent anyone from tampering with it.</LI>
084 *   <LI>The path to a file containing a passphrase to use to generate the
085 *       encryption key.</LI>
086 *   <LI>The ID of the encryption settings definition to use to generate the
087 *       encryption key.</LI>
088 *   <LI>The maximum rate in megabytes per second at which the backup should be
089 *       written.</LI>
090 *   <LI>The minimum number of previous full backups to retain.</LI>
091 *   <LI>The minimum age of previous full backups to retain.</LI>
092 * </UL>
093
094 */
095@NotMutable()
096@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
097public final class BackupTask
098       extends Task
099{
100  /**
101   * The fully-qualified name of the Java class that is used for the backup
102   * task.
103   */
104  static final String BACKUP_TASK_CLASS =
105       "com.unboundid.directory.server.tasks.BackupTask";
106
107
108
109  /**
110   * The name of the attribute used to specify backend IDs of the backends to
111   * archive.
112   */
113  private static final String ATTR_BACKEND_ID = "ds-task-backup-backend-id";
114
115
116
117  /**
118   * The name of the attribute used to indicate whether to back up the contents
119   * of all supported backends.
120   */
121  private static final String ATTR_BACKUP_ALL = "ds-task-backup-all";
122
123
124
125  /**
126   * The name of the attribute used to specify the path to the directory in
127   * which the backup is to be written.
128   */
129  private static final String ATTR_BACKUP_DIRECTORY =
130       "ds-backup-directory-path";
131
132
133
134  /**
135   * The name of the attribute used to specify the backup ID for the backup.
136   */
137  private static final String ATTR_BACKUP_ID = "ds-backup-id";
138
139
140
141  /**
142   * The name of the attribute used to indicate whether to compress the backup.
143   */
144  private static final String ATTR_COMPRESS = "ds-task-backup-compress";
145
146
147
148  /**
149   * The name of the attribute used to indicate whether to encrypt the backup.
150   */
151  private static final String ATTR_ENCRYPT = "ds-task-backup-encrypt";
152
153
154
155  /**
156   * The name of the attribute used to specify the path to a file that contains
157   * the passphrase to use to generate the encryption key.
158   */
159  private static final String ATTR_ENCRYPTION_PASSPHRASE_FILE =
160       "ds-task-backup-encryption-passphrase-file";
161
162
163
164  /**
165   * The name of the attribute used to specify the path to a file that contains
166   * the ID of the encryption settings definition to use to generate the
167   * encryption key.
168   */
169  private static final String ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID =
170       "ds-task-backup-encryption-settings-definition-id";
171
172
173
174  /**
175   * The name of the attribute used to indicate whether to create a hash of the
176   * backup.
177   */
178  private static final String ATTR_HASH = "ds-task-backup-hash";
179
180
181
182  /**
183   * The name of the attribute used to indicate whether to perform an
184   * incremental backup rather than a full backup.
185   */
186  private static final String ATTR_INCREMENTAL = "ds-task-backup-incremental";
187
188
189
190  /**
191   * The name of the attribute used to specify the backup ID of the backup
192   * on which to base the incremental backup.
193   */
194  private static final String ATTR_INCREMENTAL_BASE_ID =
195       "ds-task-backup-incremental-base-id";
196
197
198
199  /**
200   * The name of the attribute used to specify the maximum backup write rate in
201   * megabytes per second.
202   */
203  private static final String ATTR_MAX_MEGABYTES_PER_SECOND =
204       "ds-task-backup-max-megabytes-per-second";
205
206
207
208  /**
209   * The name of the attribute used to specify the minimum age of previous full
210   * backups to retain.
211   */
212  private static final String ATTR_RETAIN_PREVIOUS_FULL_BACKUP_AGE =
213       "ds-task-backup-retain-previous-full-backup-age";
214
215
216
217  /**
218   * The name of the attribute used to specify the number of previous full
219   * backups to retain.
220   */
221  private static final String ATTR_RETAIN_PREVIOUS_FULL_BACKUP_COUNT =
222       "ds-task-backup-retain-previous-full-backup-count";
223
224
225
226  /**
227   * The name of the attribute used to indicate whether to sign the hash of the
228   * backup.
229   */
230  private static final String ATTR_SIGN_HASH = "ds-task-backup-sign-hash";
231
232
233
234  /**
235   * The name of the object class used in backup task entries.
236   */
237  private static final String OC_BACKUP_TASK = "ds-task-backup";
238
239
240
241  /**
242   * The task property that will be used for the backup directory.
243   */
244  private static final TaskProperty PROPERTY_BACKUP_DIRECTORY =
245       new TaskProperty(ATTR_BACKUP_DIRECTORY,
246            INFO_DISPLAY_NAME_BACKUP_DIRECTORY.get(),
247            INFO_DESCRIPTION_BACKUP_DIRECTORY_BACKUP.get(),
248            String.class, true, false, false);
249
250
251
252  /**
253   * The task property that will be used for the backend ID.
254   */
255  private static final TaskProperty PROPERTY_BACKEND_ID =
256       new TaskProperty(ATTR_BACKEND_ID, INFO_DISPLAY_NAME_BACKEND_ID.get(),
257            INFO_DESCRIPTION_BACKEND_ID_BACKUP.get(), String.class, false, true,
258            false);
259
260
261
262  /**
263   * The task property that will be used for the backup ID.
264   */
265  private static final TaskProperty PROPERTY_BACKUP_ID =
266       new TaskProperty(ATTR_BACKUP_ID, INFO_DISPLAY_NAME_BACKUP_ID.get(),
267            INFO_DESCRIPTION_BACKUP_ID_BACKUP.get(), String.class, false, false,
268            true);
269
270
271
272  /**
273   * The task property that will be used for the incremental flag.
274   */
275  private static final TaskProperty PROPERTY_INCREMENTAL =
276       new TaskProperty(ATTR_INCREMENTAL, INFO_DISPLAY_NAME_INCREMENTAL.get(),
277            INFO_DESCRIPTION_INCREMENTAL.get(), Boolean.class, false, false,
278            false);
279
280
281
282  /**
283   * The task property that will be used for the incremental base ID.
284   */
285  private static final TaskProperty PROPERTY_INCREMENTAL_BASE_ID =
286       new TaskProperty(ATTR_INCREMENTAL_BASE_ID,
287            INFO_DISPLAY_NAME_INCREMENTAL_BASE_ID.get(),
288            INFO_DESCRIPTION_INCREMENTAL_BASE_ID.get(), String.class, false,
289            false, true);
290
291
292
293  /**
294   * The task property that will be used for the compress flag.
295   */
296  private static final TaskProperty PROPERTY_COMPRESS =
297       new TaskProperty(ATTR_COMPRESS, INFO_DISPLAY_NAME_COMPRESS.get(),
298            INFO_DESCRIPTION_COMPRESS_BACKUP.get(), Boolean.class, false, false,
299            false);
300
301
302
303  /**
304   * The task property that will be used for the encrypt flag.
305   */
306  private static final TaskProperty PROPERTY_ENCRYPT =
307       new TaskProperty(ATTR_ENCRYPT, INFO_DISPLAY_NAME_ENCRYPT.get(),
308            INFO_DESCRIPTION_ENCRYPT_BACKUP.get(), Boolean.class, false, false,
309            false);
310
311
312
313  /**
314   * The task property that will be used for the encryption passphrase file.
315   */
316  private static final TaskProperty PROPERTY_ENCRYPTION_PASSPHRASE_FILE =
317       new TaskProperty(ATTR_ENCRYPTION_PASSPHRASE_FILE,
318            INFO_DISPLAY_NAME_ENCRYPTION_PASSPHRASE_FILE.get(),
319            INFO_DESCRIPTION_ENCRYPTION_PASSPHRASE_FILE.get(),
320            String.class, false, false, true);
321
322
323
324  /**
325   * The task property that will be used for the encryption settings definition
326   * ID.
327   */
328  private static final TaskProperty PROPERTY_ENCRYPTION_SETTINGS_DEFINITION_ID =
329       new TaskProperty(ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID,
330            INFO_DISPLAY_NAME_ENCRYPTION_SETTINGS_DEFINITION_ID.get(),
331            INFO_DESCRIPTION_ENCRYPTION_SETTINGS_DEFINITION_ID.get(),
332            String.class, false, false, true);
333
334
335
336  /**
337   * The task property that will be used for the hash flag.
338   */
339  private static final TaskProperty PROPERTY_HASH =
340       new TaskProperty(ATTR_HASH, INFO_DISPLAY_NAME_HASH.get(),
341            INFO_DESCRIPTION_HASH_BACKUP.get(), Boolean.class, false, false,
342            false);
343
344
345
346  /**
347   * The task property that will be used for the sign hash flag.
348   */
349  private static final TaskProperty PROPERTY_SIGN_HASH =
350       new TaskProperty(ATTR_SIGN_HASH, INFO_DISPLAY_NAME_SIGN_HASH.get(),
351            INFO_DESCRIPTION_SIGN_HASH_BACKUP.get(), Boolean.class, false,
352            false, false);
353
354
355
356  /**
357   * The task property that will be used for the maximum write rate in megabytes
358   * per second.
359   */
360  private static final TaskProperty PROPERTY_MAX_MEGABYTES_PER_SECOND =
361       new TaskProperty(ATTR_MAX_MEGABYTES_PER_SECOND,
362            INFO_DISPLAY_NAME_BACKUP_MAX_MEGABYTES_PER_SECOND.get(),
363            INFO_DESCRIPTION_BACKUP_MAX_MEGABYTES_PER_SECOND.get(),
364            Long.class, false, false, true);
365
366
367
368  /**
369   * The task property that will be used for the retain previous full backup
370   * age.
371   */
372  private static final TaskProperty PROPERTY_RETAIN_PREVIOUS_FULL_BACKUP_AGE =
373       new TaskProperty(ATTR_RETAIN_PREVIOUS_FULL_BACKUP_AGE,
374            INFO_DISPLAY_NAME_BACKUP_RETAIN_AGE.get(),
375            INFO_DESCRIPTION_BACKUP_RETAIN_AGE.get(),
376            String.class, false, false, true);
377
378
379
380  /**
381   * The task property that will be used for the retain previous full backup
382   * count.
383   */
384  private static final TaskProperty PROPERTY_RETAIN_PREVIOUS_FULL_BACKUP_COUNT =
385       new TaskProperty(ATTR_RETAIN_PREVIOUS_FULL_BACKUP_COUNT,
386            INFO_DISPLAY_NAME_BACKUP_RETAIN_COUNT.get(),
387            INFO_DESCRIPTION_BACKUP_RETAIN_COUNT.get(),
388            Long.class, false, false, true);
389
390
391
392  /**
393   * The serial version UID for this serializable class.
394   */
395  private static final long serialVersionUID = 2637190942057174423L;
396
397
398
399  // Indicates whether to compress the backup.
400  private final boolean compress;
401
402  // Indicates whether to encrypt the backup.
403  private final boolean encrypt;
404
405  // Indicates whether to generate a hash of the backup.
406  private final boolean hash;
407
408  // Indicates whether to sign the backup hash.
409  private final boolean signHash;
410
411  // Indicates whether to perform an incremental backup.
412  private final boolean incremental;
413
414  // The maximum backup write rate in megabytes per second.
415  private final Integer maxMegabytesPerSecond;
416
417  // The retain previous full backup count.
418  private final Integer retainPreviousFullBackupCount;
419
420  // The backend IDs of the backends to back up.
421  private final List<String> backendIDs;
422
423  // The path to the directory in which to write the backup.
424  private final String backupDirectory;
425
426  // The backup ID to use for the backup.
427  private final String backupID;
428
429  // The path to a file containing the passphrase to use to generate the
430  // encryption key.
431  private final String encryptionPassphraseFile;
432
433  // The identifier for the encryption settings definition to use to generate
434  // the encryption key.
435  private final String encryptionSettingsDefinitionID;
436
437  // The backup ID of the backup to use as the base for the incremental backup.
438  private final String incrementalBaseID;
439
440  // The retain previous full backup age.
441  private final String retainPreviousFullBackupAge;
442
443
444
445  /**
446   * Creates a new uninitialized backup task instance which should only be
447   * used for obtaining general information about this task, including the task
448   * name, description, and supported properties.  Attempts to use a task
449   * created with this constructor for any other reason will likely fail.
450   */
451  public BackupTask()
452  {
453    compress = false;
454    encrypt = false;
455    hash = false;
456    signHash = false;
457    incremental = false;
458    maxMegabytesPerSecond = null;
459    retainPreviousFullBackupCount = null;
460    backendIDs = null;
461    backupDirectory = null;
462    backupID = null;
463    encryptionPassphraseFile = null;
464    encryptionSettingsDefinitionID = null;
465    incrementalBaseID = null;
466    retainPreviousFullBackupAge = null;
467  }
468
469
470
471  /**
472   * Creates a new backup task with the provided information.
473   *
474   * @param  taskID           The task ID to use for this task.  If it is
475   *                          {@code null} then a UUID will be generated for use
476   *                          as the task ID.
477   * @param  backupDirectory  The path to the directory on the server into which
478   *                          the backup should be written.  If a single backend
479   *                          is to be archived, then this should be the path to
480   *                          the specific backup directory for that backend.
481   *                          If multiple backends are to be archived, then this
482   *                          should be the parent of the directories for each
483   *                          of the backends.  It must not be {@code null}.
484   * @param  backendID        The backend ID of the backend to back up.  It may
485   *                          be {@code null} if all supported backends should
486   *                          be backed up.
487   */
488  public BackupTask(final String taskID, final String backupDirectory,
489                    final String backendID)
490  {
491    this(taskID, backupDirectory,
492         ((backendID == null) ? null : Collections.singletonList(backendID)),
493         null, false, null, false, false, false, false, null, null, null, null,
494         null);
495  }
496
497
498
499  /**
500   * Creates a new restore task with the provided information.
501   *
502   * @param  taskID                  The task ID to use for this task.  If it is
503   *                                 {@code null} then a UUID will be generated
504   *                                 for use as the task ID.
505   * @param  backupDirectory         The path to the directory on the server
506   *                                 into which the backup should be written.
507   *                                 If a single backend is to be archived, then
508   *                                 this should be the path to the specific
509   *                                 backup directory for that backend.  If
510   *                                 multiple backends are to be archived, then
511   *                                 this should be the parent of the
512   *                                 directories for each of the backends.  It
513   *                                 must not be {@code null}.
514   * @param  backendIDs              A list of the backend IDs of the backends
515   *                                 to archive.  It may be {@code null} or
516   *                                 empty if all supported backends should be
517   *                                 archived.
518   * @param  backupID                The backup ID to use for this backup.  It
519   *                                 may be {@code null} to indicate that the
520   *                                 server should generate the backup ID.
521   * @param  incremental             Indicates whether to perform an incremental
522   *                                 backup rather than a full backup.
523   * @param  incrementalBaseID       The backup ID of the existing backup on
524   *                                 which to base the incremental backup.  It
525   *                                 may be {@code null} if this is not an
526   *                                 incremental backup or if it should be based
527   *                                 on the most recent backup.
528   * @param  compress                Indicates whether the backup should be
529   *                                 compressed.
530   * @param  encrypt                 Indicates whether the backup should be
531   *                                 encrypted.
532   * @param  hash                    Indicates whether to generate a hash of the
533   *                                 backup contents.
534   * @param  signHash                Indicates whether to sign the hash of the
535   *                                 backup contents.
536   * @param  scheduledStartTime      The time that this task should start
537   *                                 running.
538   * @param  dependencyIDs           The list of task IDs that will be required
539   *                                 to complete before this task will be
540   *                                 eligible to start.
541   * @param  failedDependencyAction  Indicates what action should be taken if
542   *                                 any of the dependencies for this task do
543   *                                 not complete successfully.
544   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
545   *                                 that should be notified when this task
546   *                                 completes.
547   * @param  notifyOnError           The list of e-mail addresses of individuals
548   *                                 that should be notified if this task does
549   *                                 not complete successfully.
550   */
551  public BackupTask(final String taskID, final String backupDirectory,
552                    final List<String> backendIDs, final String backupID,
553                    final boolean incremental, final String incrementalBaseID,
554                    final boolean compress, final boolean encrypt,
555                    final boolean hash, final boolean signHash,
556                    final Date scheduledStartTime,
557                    final List<String> dependencyIDs,
558                    final FailedDependencyAction failedDependencyAction,
559                    final List<String> notifyOnCompletion,
560                    final List<String> notifyOnError)
561  {
562    this(taskID, backupDirectory, backendIDs, backupID, incremental,
563         incrementalBaseID, compress, encrypt, null, null, hash, signHash,
564         null, null, null, scheduledStartTime, dependencyIDs,
565         failedDependencyAction, notifyOnCompletion, notifyOnError);
566  }
567
568
569
570  /**
571   * Creates a new restore task with the provided information.
572   *
573   * @param  taskID                          The task ID to use for this task.
574   *                                         If it is {@code null} then a UUID
575   *                                         will be generated for use as the
576   *                                         task ID.
577   * @param  backupDirectory                 The path to the directory on the
578   *                                         server into which the backup should
579   *                                         be written.  If a single backend is
580   *                                         to be archived, then this should be
581   *                                         the path to the specific backup
582   *                                         directory for that backend.  If
583   *                                         multiple backends are to be
584   *                                         archived, then this should be the
585   *                                         parent of the directories for each
586   *                                         of the backends.  It must not be
587   *                                         {@code null}.
588   * @param  backendIDs                      A list of the backend IDs of the
589   *                                         backends to archive.  It may be
590   *                                         {@code null} or empty if all
591   *                                         supported backends should be
592   *                                         archived.
593   * @param  backupID                        The backup ID to use for this
594   *                                         backup.  It may be {@code null} to
595   *                                         indicate that the server should
596   *                                         generate the backup ID.
597   * @param  incremental                     Indicates whether to perform an
598   *                                         incremental backup rather than a
599   *                                         full backup.
600   * @param  incrementalBaseID               The backup ID of the existing
601   *                                         backup on which to base the
602   *                                         incremental backup.  It may be
603   *                                         {@code null} if this is not an
604   *                                         incremental backup or if it should
605   *                                         be based on the most recent backup.
606   * @param  compress                        Indicates whether the backup should
607   *                                         be compressed.
608   * @param  encrypt                         Indicates whether the backup should
609   *                                         be encrypted.
610   * @param  encryptionPassphraseFile        The path to a file containing the
611   *                                         passphrase to use to generate the
612   *                                         encryption key.  It amy be
613   *                                         {@code null} if the backup is not
614   *                                         to be encrypted, or if the key
615   *                                         should be obtained in some other
616   *                                         way.
617   * @param  encryptionSettingsDefinitionID  The ID of the encryption settings
618   *                                         definition use to generate the
619   *                                         encryption key.  It may be
620   *                                         {@code null} if the backup is not
621   *                                         to be encrypted, or if the key
622   *                                         should be obtained in some other
623   *                                         way.
624   * @param  hash                            Indicates whether to generate a
625   *                                         hash of the backup contents.
626   * @param  signHash                        Indicates whether to sign the hash
627   *                                         of the backup contents.
628   * @param  maxMegabytesPerSecond           The maximum rate in megabytes per
629   *                                         second at which the backup should
630   *                                         be written.
631   * @param  retainPreviousFullBackupCount   The minimum number of previous
632   *                                         backups to retain.
633   * @param  retainPreviousFullBackupAge     A string representation of the
634   *                                         minimum age of previous backups to
635   *                                         retain.  The age should be
636   *                                         formatted in the same way as values
637   *                                         for the {@link DurationArgument}
638   *                                         class.
639   * @param  scheduledStartTime              The time that this task should
640   *                                         start running.
641   * @param  dependencyIDs                   The list of task IDs that will be
642   *                                         required to complete before this
643   *                                         task will be eligible to start.
644   * @param  failedDependencyAction          Indicates what action should be
645   *                                         taken if any of the dependencies
646   *                                         for this task do not complete
647   *                                         successfully.
648   * @param  notifyOnCompletion              The list of e-mail addresses of
649   *                                         individuals that should be notified
650   *                                         when this task completes.
651   * @param  notifyOnError                   The list of e-mail addresses of
652   *                                         individuals that should be notified
653   *                                         if this task does not complete
654   *                                         successfully.
655   */
656  public BackupTask(final String taskID, final String backupDirectory,
657                    final List<String> backendIDs, final String backupID,
658                    final boolean incremental, final String incrementalBaseID,
659                    final boolean compress, final boolean encrypt,
660                    final String encryptionPassphraseFile,
661                    final String encryptionSettingsDefinitionID,
662                    final boolean hash, final boolean signHash,
663                    final Integer maxMegabytesPerSecond,
664                    final Integer retainPreviousFullBackupCount,
665                    final String retainPreviousFullBackupAge,
666                    final Date scheduledStartTime,
667                    final List<String> dependencyIDs,
668                    final FailedDependencyAction failedDependencyAction,
669                    final List<String> notifyOnCompletion,
670                    final List<String> notifyOnError)
671  {
672    this(taskID, backupDirectory, backendIDs, backupID, incremental,
673         incrementalBaseID, compress, encrypt, encryptionPassphraseFile,
674         encryptionSettingsDefinitionID, hash, signHash, maxMegabytesPerSecond,
675         retainPreviousFullBackupCount, retainPreviousFullBackupAge,
676         scheduledStartTime, dependencyIDs, failedDependencyAction, null,
677         notifyOnCompletion, null, notifyOnError, null, null, null);
678  }
679
680
681
682  /**
683   * Creates a new restore task with the provided information.
684   *
685   * @param  taskID                          The task ID to use for this task.
686   *                                         If it is {@code null} then a UUID
687   *                                         will be generated for use as the
688   *                                         task ID.
689   * @param  backupDirectory                 The path to the directory on the
690   *                                         server into which the backup should
691   *                                         be written.  If a single backend is
692   *                                         to be archived, then this should be
693   *                                         the path to the specific backup
694   *                                         directory for that backend.  If
695   *                                         multiple backends are to be
696   *                                         archived, then this should be the
697   *                                         parent of the directories for each
698   *                                         of the backends.  It must not be
699   *                                         {@code null}.
700   * @param  backendIDs                      A list of the backend IDs of the
701   *                                         backends to archive.  It may be
702   *                                         {@code null} or empty if all
703   *                                         supported backends should be
704   *                                         archived.
705   * @param  backupID                        The backup ID to use for this
706   *                                         backup.  It may be {@code null} to
707   *                                         indicate that the server should
708   *                                         generate the backup ID.
709   * @param  incremental                     Indicates whether to perform an
710   *                                         incremental backup rather than a
711   *                                         full backup.
712   * @param  incrementalBaseID               The backup ID of the existing
713   *                                         backup on which to base the
714   *                                         incremental backup.  It may be
715   *                                         {@code null} if this is not an
716   *                                         incremental backup or if it should
717   *                                         be based on the most recent backup.
718   * @param  compress                        Indicates whether the backup should
719   *                                         be compressed.
720   * @param  encrypt                         Indicates whether the backup should
721   *                                         be encrypted.
722   * @param  encryptionPassphraseFile        The path to a file containing the
723   *                                         passphrase to use to generate the
724   *                                         encryption key.  It amy be
725   *                                         {@code null} if the backup is not
726   *                                         to be encrypted, or if the key
727   *                                         should be obtained in some other
728   *                                         way.
729   * @param  encryptionSettingsDefinitionID  The ID of the encryption settings
730   *                                         definition use to generate the
731   *                                         encryption key.  It may be
732   *                                         {@code null} if the backup is not
733   *                                         to be encrypted, or if the key
734   *                                         should be obtained in some other
735   *                                         way.
736   * @param  hash                            Indicates whether to generate a
737   *                                         hash of the backup contents.
738   * @param  signHash                        Indicates whether to sign the hash
739   *                                         of the backup contents.
740   * @param  maxMegabytesPerSecond           The maximum rate in megabytes per
741   *                                         second at which the backup should
742   *                                         be written.
743   * @param  retainPreviousFullBackupCount   The minimum number of previous
744   *                                         backups to retain.
745   * @param  retainPreviousFullBackupAge     A string representation of the
746   *                                         minimum age of previous backups to
747   *                                         retain.  The age should be
748   *                                         formatted in the same way as values
749   *                                         for the {@link DurationArgument}
750   *                                         class.
751   * @param  scheduledStartTime              The time that this task should
752   *                                         start running.
753   * @param  dependencyIDs                   The list of task IDs that will be
754   *                                         required to complete before this
755   *                                         task will be eligible to start.
756   * @param  failedDependencyAction          Indicates what action should be
757   *                                         taken if any of the dependencies
758   *                                         for this task do not complete
759   *                                         successfully.
760   * @param  notifyOnStart                   The list of e-mail addresses of
761   *                                         individuals that should be notified
762   *                                         when this task starts running.
763   * @param  notifyOnCompletion              The list of e-mail addresses of
764   *                                         individuals that should be notified
765   *                                         when this task completes.
766   * @param  notifyOnSuccess                 The list of e-mail addresses of
767   *                                         individuals that should be notified
768   *                                         if this task completes
769   *                                         successfully.
770   * @param  notifyOnError                   The list of e-mail addresses of
771   *                                         individuals that should be notified
772   *                                         if this task does not complete
773   *                                         successfully.
774   * @param  alertOnStart                    Indicates whether the server should
775   *                                         send an alert notification when
776   *                                         this task starts.
777   * @param  alertOnSuccess                  Indicates whether the server should
778   *                                         send an alert notification if this
779   *                                         task completes successfully.
780   * @param  alertOnError                    Indicates whether the server should
781   *                                         send an alert notification if this
782   *                                         task fails to complete
783   *                                         successfully.
784   */
785  public BackupTask(final String taskID, final String backupDirectory,
786                    final List<String> backendIDs, final String backupID,
787                    final boolean incremental, final String incrementalBaseID,
788                    final boolean compress, final boolean encrypt,
789                    final String encryptionPassphraseFile,
790                    final String encryptionSettingsDefinitionID,
791                    final boolean hash, final boolean signHash,
792                    final Integer maxMegabytesPerSecond,
793                    final Integer retainPreviousFullBackupCount,
794                    final String retainPreviousFullBackupAge,
795                    final Date scheduledStartTime,
796                    final List<String> dependencyIDs,
797                    final FailedDependencyAction failedDependencyAction,
798                    final List<String> notifyOnStart,
799                    final List<String> notifyOnCompletion,
800                    final List<String> notifyOnSuccess,
801                    final List<String> notifyOnError,
802                    final Boolean alertOnStart, final Boolean alertOnSuccess,
803                    final Boolean alertOnError)
804  {
805    super(taskID, BACKUP_TASK_CLASS, scheduledStartTime,
806         dependencyIDs, failedDependencyAction, notifyOnStart,
807         notifyOnCompletion, notifyOnSuccess,  notifyOnError, alertOnStart,
808         alertOnSuccess, alertOnError);
809
810    Validator.ensureNotNull(backupDirectory);
811
812    this.backupDirectory = backupDirectory;
813    this.backupID = backupID;
814    this.incremental = incremental;
815    this.incrementalBaseID = incrementalBaseID;
816    this.compress = compress;
817    this.encrypt = encrypt;
818    this.encryptionPassphraseFile = encryptionPassphraseFile;
819    this.encryptionSettingsDefinitionID = encryptionSettingsDefinitionID;
820    this.hash = hash;
821    this.signHash = signHash;
822    this.maxMegabytesPerSecond = maxMegabytesPerSecond;
823    this.retainPreviousFullBackupCount = retainPreviousFullBackupCount;
824    this.retainPreviousFullBackupAge = retainPreviousFullBackupAge;
825
826    if (backendIDs == null)
827    {
828      this.backendIDs = Collections.emptyList();
829    }
830    else
831    {
832      this.backendIDs = Collections.unmodifiableList(backendIDs);
833    }
834  }
835
836
837
838  /**
839   * Creates a new backup task from the provided entry.
840   *
841   * @param  entry  The entry to use to create this backup task.
842   *
843   * @throws  TaskException  If the provided entry cannot be parsed as a backup
844   *                         task entry.
845   */
846  public BackupTask(final Entry entry)
847         throws TaskException
848  {
849    super(entry);
850
851
852    // Get the backup directory.  It must be present.
853    backupDirectory = entry.getAttributeValue(ATTR_BACKUP_DIRECTORY);
854    if (backupDirectory == null)
855    {
856      throw new TaskException(ERR_BACKUP_NO_BACKUP_DIRECTORY.get(
857                                   getTaskEntryDN()));
858    }
859
860
861    // Get the set of backend IDs.  It may be absent.
862    backendIDs = parseStringList(entry, ATTR_BACKEND_ID);
863
864
865    // Get the backup ID.  It may be absent.
866    backupID = entry.getAttributeValue(ATTR_BACKUP_ID);
867
868
869    // Get the incremental flag.  It may be absent.
870    incremental = parseBooleanValue(entry, ATTR_INCREMENTAL, false);
871
872
873    // Get the incremental base ID.  It may be absent.
874    incrementalBaseID = entry.getAttributeValue(ATTR_INCREMENTAL_BASE_ID);
875
876
877    // Determine whether to compress the backup.  It may be absent.
878    compress = parseBooleanValue(entry, ATTR_COMPRESS, false);
879
880
881    // Determine whether to encrypt the backup.  It may be absent.
882    encrypt = parseBooleanValue(entry, ATTR_ENCRYPT, false);
883
884
885    // Get the path to the encryption passphrase file.  It may be absent.
886    encryptionPassphraseFile =
887         entry.getAttributeValue(ATTR_ENCRYPTION_PASSPHRASE_FILE);
888
889
890    // Get the encryption settings definition ID.  It may be absent.
891    encryptionSettingsDefinitionID =
892         entry.getAttributeValue(ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID);
893
894
895    // Determine whether to hash the backup.  It may be absent.
896    hash = parseBooleanValue(entry, ATTR_HASH, false);
897
898
899    // Determine whether to sign the hash.  It may be absent.
900    signHash = parseBooleanValue(entry, ATTR_SIGN_HASH, false);
901
902
903    // Get the maximum write rate in megabytes per second.  It may be absent.
904    maxMegabytesPerSecond =
905         entry.getAttributeValueAsInteger(ATTR_MAX_MEGABYTES_PER_SECOND);
906
907
908    // Get the retain previous full backup count.  It may be absent.
909    retainPreviousFullBackupCount = entry.getAttributeValueAsInteger(
910         ATTR_RETAIN_PREVIOUS_FULL_BACKUP_COUNT);
911
912
913    // Get the retain previous full backup age.  It may be absent.
914    retainPreviousFullBackupAge = entry.getAttributeValue(
915         ATTR_RETAIN_PREVIOUS_FULL_BACKUP_AGE);
916  }
917
918
919
920  /**
921   * Creates a new backup task from the provided set of task properties.
922   *
923   * @param  properties  The set of task properties and their corresponding
924   *                     values to use for the task.  It must not be
925   *                     {@code null}.
926   *
927   * @throws  TaskException  If the provided set of properties cannot be used to
928   *                         create a valid backup task.
929   */
930  public BackupTask(final Map<TaskProperty,List<Object>> properties)
931         throws TaskException
932  {
933    super(BACKUP_TASK_CLASS, properties);
934
935    boolean  c           = false;
936    boolean  e           = false;
937    boolean  h           = false;
938    boolean  i           = false;
939    boolean  s           = false;
940    Integer  maxMB       = null;
941    Integer  retainCount = null;
942    String   bDir        = null;
943    String   bkID        = null;
944    String   incID       = null;
945    String   encID       = null;
946    String   encPWFile   = null;
947    String   retainAge   = null;
948    String[] beIDs       = StaticUtils.NO_STRINGS;
949
950    for (final Map.Entry<TaskProperty,List<Object>> entry :
951         properties.entrySet())
952    {
953      final TaskProperty p = entry.getKey();
954      final String attrName = p.getAttributeName();
955      final List<Object> values = entry.getValue();
956
957      if (attrName.equalsIgnoreCase(ATTR_BACKUP_DIRECTORY))
958      {
959        bDir = parseString(p, values, bDir);
960      }
961      else if (attrName.equalsIgnoreCase(ATTR_BACKEND_ID))
962      {
963        beIDs = parseStrings(p, values, beIDs);
964      }
965      else if (attrName.equalsIgnoreCase(ATTR_BACKUP_ID))
966      {
967        bkID = parseString(p, values, bkID);
968      }
969      else if (attrName.equalsIgnoreCase(ATTR_INCREMENTAL))
970      {
971        i = parseBoolean(p, values, i);
972      }
973      else if (attrName.equalsIgnoreCase(ATTR_INCREMENTAL_BASE_ID))
974      {
975        incID = parseString(p, values, incID);
976      }
977      else if (attrName.equalsIgnoreCase(ATTR_COMPRESS))
978      {
979        c = parseBoolean(p, values, c);
980      }
981      else if (attrName.equalsIgnoreCase(ATTR_ENCRYPT))
982      {
983        e = parseBoolean(p, values, e);
984      }
985      else if (attrName.equalsIgnoreCase(ATTR_ENCRYPTION_PASSPHRASE_FILE))
986      {
987        encPWFile = parseString(p, values, encPWFile);
988      }
989      else if (attrName.equalsIgnoreCase(
990           ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID))
991      {
992        encID = parseString(p, values, encID);
993      }
994      else if (attrName.equalsIgnoreCase(ATTR_HASH))
995      {
996        h = parseBoolean(p, values, h);
997      }
998      else if (attrName.equalsIgnoreCase(ATTR_SIGN_HASH))
999      {
1000        s = parseBoolean(p, values, s);
1001      }
1002      else if (attrName.equalsIgnoreCase(ATTR_MAX_MEGABYTES_PER_SECOND))
1003      {
1004        final Long maxMBLong = parseLong(p, values, null);
1005        if (maxMBLong == null)
1006        {
1007          maxMB = null;
1008        }
1009        else
1010        {
1011          maxMB = maxMBLong.intValue();
1012        }
1013      }
1014      else if (attrName.equalsIgnoreCase(
1015           ATTR_RETAIN_PREVIOUS_FULL_BACKUP_COUNT))
1016      {
1017        final Long retainCountLong = parseLong(p, values, null);
1018        if (retainCountLong == null)
1019        {
1020          retainCount = null;
1021        }
1022        else
1023        {
1024          retainCount = retainCountLong.intValue();
1025        }
1026      }
1027      else if (attrName.equalsIgnoreCase(ATTR_RETAIN_PREVIOUS_FULL_BACKUP_AGE))
1028      {
1029        retainAge = parseString(p, values, retainAge);
1030      }
1031    }
1032
1033    if (bDir == null)
1034    {
1035      throw new TaskException(ERR_BACKUP_NO_BACKUP_DIRECTORY.get(
1036                                   getTaskEntryDN()));
1037    }
1038
1039    backupDirectory = bDir;
1040    backendIDs = Arrays.asList(beIDs);
1041    backupID = bkID;
1042    incremental = i;
1043    incrementalBaseID = incID;
1044    compress = c;
1045    encrypt = e;
1046    encryptionPassphraseFile = encPWFile;
1047    encryptionSettingsDefinitionID = encID;
1048    hash = h;
1049    signHash = s;
1050    maxMegabytesPerSecond = maxMB;
1051    retainPreviousFullBackupCount = retainCount;
1052    retainPreviousFullBackupAge = retainAge;
1053  }
1054
1055
1056
1057  /**
1058   * {@inheritDoc}
1059   */
1060  @Override()
1061  public String getTaskName()
1062  {
1063    return INFO_TASK_NAME_BACKUP.get();
1064  }
1065
1066
1067
1068  /**
1069   * {@inheritDoc}
1070   */
1071  @Override()
1072  public String getTaskDescription()
1073  {
1074    return INFO_TASK_DESCRIPTION_BACKUP.get();
1075  }
1076
1077
1078
1079  /**
1080   * Retrieves the path to the backup directory in which the backup files should
1081   * be written.  If a single backend is to be archived, then this will be the
1082   * directory in which the backup files are written.  If multiple backends are
1083   * to be archived, then this will be the parent of the directories containing
1084   * the backups for each backend.
1085   *
1086   * @return  The path to the backup directory in which the backup files should
1087   *          be written.
1088   */
1089  public String getBackupDirectory()
1090  {
1091    return backupDirectory;
1092  }
1093
1094
1095
1096  /**
1097   * Indicates whether the server should back up all supported backends.
1098   *
1099   * @return  {@code true} if the server should back up all supported backends,
1100   *          or {@code false} if it should back up a specified backend or set
1101   *          of backends.
1102   */
1103  public boolean backupAll()
1104  {
1105    return backendIDs.isEmpty();
1106  }
1107
1108
1109
1110  /**
1111   * Retrieves the set of backend IDs for the backends that should be archived.
1112   *
1113   * @return  The set of backend IDs for the backends that should be archived,
1114   *          or an empty list if the server should back up all supported
1115   *          backends.
1116   */
1117  public List<String> getBackendIDs()
1118  {
1119    return backendIDs;
1120  }
1121
1122
1123
1124  /**
1125   * Retrieves the backup ID for the backup to generate.
1126   *
1127   * @return  The backup ID for the backup to generate, or {@code null} if the
1128   *          server should generate a backup ID.
1129   */
1130  public String getBackupID()
1131  {
1132    return backupID;
1133  }
1134
1135
1136
1137  /**
1138   * Indicates whether the server should attempt to perform an incremental
1139   * backup rather than a full backup.
1140   *
1141   * @return  {@code true} if the server should attempt to perform an
1142   *          incremental backup, or {@code false} for a full backup.
1143   */
1144  public boolean incremental()
1145  {
1146    return incremental;
1147  }
1148
1149
1150
1151  /**
1152   * Retrieves the backup ID of the existing backup on which the incremental
1153   * backup should be based.
1154   *
1155   * @return  The backup ID of the existing backup on which the incremental
1156   *          backup should be based, or {@code null} if it is not an
1157   *          incremental backup or the server should use the most recent
1158   *          backup available as the base for the new incremental backup.
1159   */
1160  public String getIncrementalBaseID()
1161  {
1162    return incrementalBaseID;
1163  }
1164
1165
1166
1167  /**
1168   * Indicates whether the backup should be compressed.
1169   *
1170   * @return  {@code true} if the backup should be compressed, or {@code false}
1171   *          if not.
1172   */
1173  public boolean compress()
1174  {
1175    return compress;
1176  }
1177
1178
1179
1180  /**
1181   * Indicates whether the backup should be encrypted.
1182   *
1183   * @return  {@code true} if the backup should be encrypted, or {@code false}
1184   *          if not.
1185   */
1186  public boolean encrypt()
1187  {
1188    return encrypt;
1189  }
1190
1191
1192
1193  /**
1194   * Retrieves the path to a file that contains the passphrase to use to
1195   * generate the encryption key.
1196   *
1197   * @return  The path to a file that contains the passphrase to use to
1198   *          generate the encryption key, or {@code null} if the backup should
1199   *          not be encrypted or if the encryption key should be obtained
1200   *          through some other means.
1201   */
1202  public String getEncryptionPassphraseFile()
1203  {
1204    return encryptionPassphraseFile;
1205  }
1206
1207
1208
1209  /**
1210   * Retrieves the identifier of the encryption settings definition to use to
1211   * generate the encryption key.
1212   *
1213   * @return  The identifier of the encryption settings definition to use to
1214   *          generate the encryption key, or {@code null} if the backup should
1215   *          not be encrypted or if the encryption key should be obtained
1216   *          through some other means.
1217   */
1218  public String getEncryptionSettingsDefinitionID()
1219  {
1220    return encryptionSettingsDefinitionID;
1221  }
1222
1223
1224
1225  /**
1226   * Indicates whether the server should generate a hash of the backup.
1227   *
1228   * @return  {@code true} if the server should generate a hash of the backup,
1229   *          or {@code false} if not.
1230   */
1231  public boolean hash()
1232  {
1233    return hash;
1234  }
1235
1236
1237
1238  /**
1239   * Indicates whether the server should sign the backup hash.
1240   *
1241   * @return  {@code true} if the server should sign the backup hash, or
1242   *          {@code false} if not.
1243   */
1244  public boolean signHash()
1245  {
1246    return signHash;
1247  }
1248
1249
1250
1251  /**
1252   * Retrieves the maximum rate, in megabytes per second, at which the backup
1253   * should be written.
1254   *
1255   * @return  The maximum rate, in megabytes per second, at which the backup
1256   *          should be written, or {@code null} if the writing should not be
1257   *          rate limited.
1258   */
1259  public Integer getMaxMegabytesPerSecond()
1260  {
1261    return maxMegabytesPerSecond;
1262  }
1263
1264
1265
1266  /**
1267   * Retrieves the minimum number of previous full backups that should be
1268   * retained if the new backup is created successfully.
1269   *
1270   * @return  The minimum number of previous full backups that should be
1271   *          retained if the new backup is created successfully, or
1272   *          {@code null} if no backups should be removed or if the backup age
1273   *          should be the only retention criteria.
1274   */
1275  public Integer getRetainPreviousFullBackupCount()
1276  {
1277    return retainPreviousFullBackupCount;
1278  }
1279
1280
1281
1282  /**
1283   * Retrieves a string representation of the minimum age of previous full
1284   * backups that should be retained if the new backup is created successfully.
1285   *
1286   * @return  A string representation fo the minimum age of previous full
1287   *          backups that should be retained if the new backup is created
1288   *          successfully, or {@code null} if no backups should be removed or
1289   *          if the backup count should be the only retention criteria.
1290   */
1291  public String getRetainPreviousFullBackupAge()
1292  {
1293    return retainPreviousFullBackupAge;
1294  }
1295
1296
1297
1298  /**
1299   * {@inheritDoc}
1300   */
1301  @Override()
1302  protected List<String> getAdditionalObjectClasses()
1303  {
1304    return Collections.singletonList(OC_BACKUP_TASK);
1305  }
1306
1307
1308
1309  /**
1310   * {@inheritDoc}
1311   */
1312  @Override()
1313  protected List<Attribute> getAdditionalAttributes()
1314  {
1315    final ArrayList<Attribute> attrs = new ArrayList<>(20);
1316
1317    attrs.add(new Attribute(ATTR_BACKUP_DIRECTORY, backupDirectory));
1318    attrs.add(new Attribute(ATTR_INCREMENTAL,  String.valueOf(incremental)));
1319    attrs.add(new Attribute(ATTR_COMPRESS, String.valueOf(compress)));
1320    attrs.add(new Attribute(ATTR_ENCRYPT, String.valueOf(encrypt)));
1321    attrs.add(new Attribute(ATTR_HASH, String.valueOf(hash)));
1322    attrs.add(new Attribute(ATTR_SIGN_HASH, String.valueOf(signHash)));
1323
1324    if (backendIDs.isEmpty())
1325    {
1326      attrs.add(new Attribute(ATTR_BACKUP_ALL, "true"));
1327    }
1328    else
1329    {
1330      attrs.add(new Attribute(ATTR_BACKEND_ID, backendIDs));
1331    }
1332
1333    if (backupID != null)
1334    {
1335      attrs.add(new Attribute(ATTR_BACKUP_ID, backupID));
1336    }
1337
1338    if (incrementalBaseID != null)
1339    {
1340      attrs.add(new Attribute(ATTR_INCREMENTAL_BASE_ID, incrementalBaseID));
1341    }
1342
1343    if (encryptionPassphraseFile != null)
1344    {
1345      attrs.add(new Attribute(ATTR_ENCRYPTION_PASSPHRASE_FILE,
1346           encryptionPassphraseFile));
1347    }
1348
1349    if (encryptionSettingsDefinitionID != null)
1350    {
1351      attrs.add(new Attribute(ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID,
1352           encryptionSettingsDefinitionID));
1353    }
1354
1355    if (maxMegabytesPerSecond != null)
1356    {
1357      attrs.add(new Attribute(ATTR_MAX_MEGABYTES_PER_SECOND,
1358           String.valueOf(maxMegabytesPerSecond)));
1359    }
1360
1361    if (retainPreviousFullBackupCount != null)
1362    {
1363      attrs.add(new Attribute(ATTR_RETAIN_PREVIOUS_FULL_BACKUP_COUNT,
1364           String.valueOf(retainPreviousFullBackupCount)));
1365    }
1366
1367    if (retainPreviousFullBackupAge != null)
1368    {
1369      attrs.add(new Attribute(ATTR_RETAIN_PREVIOUS_FULL_BACKUP_AGE,
1370           retainPreviousFullBackupAge));
1371    }
1372
1373    return attrs;
1374  }
1375
1376
1377
1378  /**
1379   * {@inheritDoc}
1380   */
1381  @Override()
1382  public List<TaskProperty> getTaskSpecificProperties()
1383  {
1384    final List<TaskProperty> propList = Arrays.asList(
1385         PROPERTY_BACKUP_DIRECTORY,
1386         PROPERTY_BACKEND_ID,
1387         PROPERTY_BACKUP_ID,
1388         PROPERTY_INCREMENTAL,
1389         PROPERTY_INCREMENTAL_BASE_ID,
1390         PROPERTY_COMPRESS,
1391         PROPERTY_ENCRYPT,
1392         PROPERTY_ENCRYPTION_PASSPHRASE_FILE,
1393         PROPERTY_ENCRYPTION_SETTINGS_DEFINITION_ID,
1394         PROPERTY_HASH,
1395         PROPERTY_SIGN_HASH,
1396         PROPERTY_MAX_MEGABYTES_PER_SECOND,
1397         PROPERTY_RETAIN_PREVIOUS_FULL_BACKUP_COUNT,
1398         PROPERTY_RETAIN_PREVIOUS_FULL_BACKUP_AGE);
1399
1400    return Collections.unmodifiableList(propList);
1401  }
1402
1403
1404
1405  /**
1406   * {@inheritDoc}
1407   */
1408  @Override()
1409  public Map<TaskProperty,List<Object>> getTaskPropertyValues()
1410  {
1411    final LinkedHashMap<TaskProperty,List<Object>> props =
1412         new LinkedHashMap<>(20);
1413
1414    props.put(PROPERTY_BACKUP_DIRECTORY,
1415         Collections.<Object>singletonList(backupDirectory));
1416
1417    props.put(PROPERTY_BACKEND_ID,
1418              Collections.<Object>unmodifiableList(backendIDs));
1419
1420    if (backupID == null)
1421    {
1422      props.put(PROPERTY_BACKUP_ID, Collections.emptyList());
1423    }
1424    else
1425    {
1426      props.put(PROPERTY_BACKUP_ID,
1427                Collections.<Object>singletonList(backupID));
1428    }
1429
1430    props.put(PROPERTY_INCREMENTAL,
1431              Collections.<Object>singletonList(incremental));
1432
1433    if (incrementalBaseID == null)
1434    {
1435      props.put(PROPERTY_INCREMENTAL_BASE_ID, Collections.emptyList());
1436    }
1437    else
1438    {
1439      props.put(PROPERTY_INCREMENTAL_BASE_ID,
1440                Collections.<Object>singletonList(incrementalBaseID));
1441    }
1442
1443    props.put(PROPERTY_COMPRESS,
1444              Collections.<Object>singletonList(compress));
1445
1446    props.put(PROPERTY_ENCRYPT,
1447              Collections.<Object>singletonList(encrypt));
1448
1449    if (encryptionPassphraseFile == null)
1450    {
1451      props.put(PROPERTY_ENCRYPTION_PASSPHRASE_FILE, Collections.emptyList());
1452    }
1453    else
1454    {
1455      props.put(PROPERTY_ENCRYPTION_PASSPHRASE_FILE,
1456         Collections.<Object>singletonList(encryptionPassphraseFile));
1457    }
1458
1459    if (encryptionSettingsDefinitionID == null)
1460    {
1461      props.put(PROPERTY_ENCRYPTION_SETTINGS_DEFINITION_ID,
1462           Collections.emptyList());
1463    }
1464    else
1465    {
1466      props.put(PROPERTY_ENCRYPTION_SETTINGS_DEFINITION_ID,
1467         Collections.<Object>singletonList(encryptionSettingsDefinitionID));
1468    }
1469
1470    props.put(PROPERTY_HASH,
1471              Collections.<Object>singletonList(hash));
1472
1473    props.put(PROPERTY_SIGN_HASH,
1474              Collections.<Object>singletonList(signHash));
1475
1476    if (maxMegabytesPerSecond == null)
1477    {
1478      props.put(PROPERTY_MAX_MEGABYTES_PER_SECOND, Collections.emptyList());
1479    }
1480    else
1481    {
1482      props.put(PROPERTY_MAX_MEGABYTES_PER_SECOND,
1483         Collections.<Object>singletonList(maxMegabytesPerSecond.longValue()));
1484    }
1485
1486    if (retainPreviousFullBackupCount == null)
1487    {
1488      props.put(PROPERTY_RETAIN_PREVIOUS_FULL_BACKUP_COUNT,
1489           Collections.emptyList());
1490    }
1491    else
1492    {
1493      props.put(PROPERTY_RETAIN_PREVIOUS_FULL_BACKUP_COUNT,
1494         Collections.<Object>singletonList(
1495              retainPreviousFullBackupCount.longValue()));
1496    }
1497
1498    if (retainPreviousFullBackupAge == null)
1499    {
1500      props.put(PROPERTY_RETAIN_PREVIOUS_FULL_BACKUP_AGE,
1501           Collections.emptyList());
1502    }
1503    else
1504    {
1505      props.put(PROPERTY_RETAIN_PREVIOUS_FULL_BACKUP_AGE,
1506         Collections.<Object>singletonList(retainPreviousFullBackupAge));
1507    }
1508
1509    props.putAll(super.getTaskPropertyValues());
1510    return Collections.unmodifiableMap(props);
1511  }
1512}