001/* 002 * Copyright 2008-2017 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2017 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.ThreadSafety; 037import com.unboundid.util.ThreadSafetyLevel; 038 039import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*; 040import static com.unboundid.util.Validator.*; 041 042 043 044/** 045 * This class defines a Directory Server task that can be used to restore a 046 * backup. 047 * <BR> 048 * <BLOCKQUOTE> 049 * <B>NOTE:</B> This class, and other classes within the 050 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 051 * supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661 052 * server products. These classes provide support for proprietary 053 * functionality or for external specifications that are not considered stable 054 * or mature enough to be guaranteed to work in an interoperable way with 055 * other types of LDAP servers. 056 * </BLOCKQUOTE> 057 * <BR> 058 * The properties that are available for use with this type of task include: 059 * <UL> 060 * <LI>The path to the backup directory in which the backup resides. This 061 * must be provided when scheduling a new task of this type.</LI> 062 * <LI>The backup ID of the backup to be restored. If this is not provided 063 * when scheduling an instance of this task, then the most recent backup 064 * in the backup directory will be selected.</LI> 065 * <LI>A flag that indicates whether to attempt to restore the backup or 066 * only to verify it to determine whether it appears to be valid (e.g., 067 * validate the digest and/or signature, make sure that the backend 068 * considers it valid, etc.).</LI> 069 * </UL> 070 071 */ 072@NotMutable() 073@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 074public final class RestoreTask 075 extends Task 076{ 077 /** 078 * The fully-qualified name of the Java class that is used for the restore 079 * task. 080 */ 081 static final String RESTORE_TASK_CLASS = 082 "com.unboundid.directory.server.tasks.RestoreTask"; 083 084 085 086 /** 087 * The name of the attribute used to specify the path to the backup directory 088 * containing the backup to restore. 089 */ 090 private static final String ATTR_BACKUP_DIRECTORY = 091 "ds-backup-directory-path"; 092 093 094 095 /** 096 * The name of the attribute used to specify the backup ID of the backup to 097 * restore. 098 */ 099 private static final String ATTR_BACKUP_ID = "ds-backup-id"; 100 101 102 103 /** 104 * The name of the attribute used to indicate whether to only verify the 105 * backup but not actually restore it. 106 */ 107 private static final String ATTR_VERIFY_ONLY = 108 "ds-task-restore-verify-only"; 109 110 111 112 /** 113 * The name of the object class used in restore task entries. 114 */ 115 private static final String OC_RESTORE_TASK = "ds-task-restore"; 116 117 118 119 /** 120 * The task property for the backup directory. 121 */ 122 private static final TaskProperty PROPERTY_BACKUP_DIRECTORY = 123 new TaskProperty(ATTR_BACKUP_DIRECTORY, 124 INFO_DISPLAY_NAME_BACKUP_DIRECTORY.get(), 125 INFO_DESCRIPTION_BACKUP_DIRECTORY_RESTORE.get(), 126 String.class, true, false, false); 127 128 129 130 /** 131 * The task property for the backup ID. 132 */ 133 private static final TaskProperty PROPERTY_BACKUP_ID = 134 new TaskProperty(ATTR_BACKUP_ID, INFO_DISPLAY_NAME_BACKUP_ID.get(), 135 INFO_DESCRIPTION_BACKUP_ID_RESTORE.get(), String.class, 136 false, false, true); 137 138 139 140 /** 141 * The task property for the verify only flag. 142 */ 143 private static final TaskProperty PROPERTY_VERIFY_ONLY = 144 new TaskProperty(ATTR_VERIFY_ONLY, INFO_DISPLAY_NAME_VERIFY_ONLY.get(), 145 INFO_DESCRIPTION_VERIFY_ONLY.get(), Boolean.class, 146 false, false, false); 147 148 149 150 /** 151 * The serial version UID for this serializable class. 152 */ 153 private static final long serialVersionUID = -196339437379274643L; 154 155 156 157 // Indicates whether to only verify the backup without restoring it. 158 private final boolean verifyOnly; 159 160 // The path to the backup directory containing the backup to restore. 161 private final String backupDirectory; 162 163 // The backup ID of the backup to restore. 164 private final String backupID; 165 166 167 168 /** 169 * Creates a new uninitialized restore task instance which should only be used 170 * for obtaining general information about this task, including the task name, 171 * description, and supported properties. Attempts to use a task created with 172 * this constructor for any other reason will likely fail. 173 */ 174 public RestoreTask() 175 { 176 verifyOnly = false; 177 backupDirectory = null; 178 backupID = null; 179 } 180 181 182 183 184 /** 185 * Creates a new restore task with the provided information. 186 * 187 * @param taskID The task ID to use for this task. If it is 188 * {@code null} then a UUID will be generated for use 189 * as the task ID. 190 * @param backupDirectory The path to the directory on the server containing 191 * the backup to restore. It may be an absolute path 192 * or relative to the server root directory. It must 193 * not be {@code null}. 194 * @param backupID The backup ID of the backup to restore. If this 195 * is {@code null} then the most recent backup in the 196 * specified backup directory will be restored. 197 * @param verifyOnly Indicates whether to only verify the backup 198 * without restoring it. 199 */ 200 public RestoreTask(final String taskID, final String backupDirectory, 201 final String backupID, final boolean verifyOnly) 202 { 203 this(taskID, backupDirectory, backupID, verifyOnly, null, null, null, null, 204 null); 205 } 206 207 208 209 /** 210 * Creates a new restore task with the provided information. 211 * 212 * @param taskID The task ID to use for this task. If it is 213 * {@code null} then a UUID will be generated 214 * for use as the task ID. 215 * @param backupDirectory The path to the directory on the server 216 * containing the backup to restore. It may 217 * be an absolute path or relative to the 218 * server root directory. It must not be 219 * {@code null}. 220 * @param backupID The backup ID of the backup to restore. If 221 * this is {@code null} then the most recent 222 * backup in the specified backup directory 223 * will be restored. 224 * @param verifyOnly Indicates whether to only verify the backup 225 * without restoring it. 226 * @param scheduledStartTime The time that this task should start 227 * running. 228 * @param dependencyIDs The list of task IDs that will be required 229 * to complete before this task will be 230 * eligible to start. 231 * @param failedDependencyAction Indicates what action should be taken if 232 * any of the dependencies for this task do 233 * not complete successfully. 234 * @param notifyOnCompletion The list of e-mail addresses of individuals 235 * that should be notified when this task 236 * completes. 237 * @param notifyOnError The list of e-mail addresses of individuals 238 * that should be notified if this task does 239 * not complete successfully. 240 */ 241 public RestoreTask(final String taskID, final String backupDirectory, 242 final String backupID, final boolean verifyOnly, 243 final Date scheduledStartTime, 244 final List<String> dependencyIDs, 245 final FailedDependencyAction failedDependencyAction, 246 final List<String> notifyOnCompletion, 247 final List<String> notifyOnError) 248 { 249 super(taskID, RESTORE_TASK_CLASS, scheduledStartTime, 250 dependencyIDs, failedDependencyAction, notifyOnCompletion, 251 notifyOnError); 252 253 ensureNotNull(backupDirectory); 254 255 this.backupDirectory = backupDirectory; 256 this.backupID = backupID; 257 this.verifyOnly = verifyOnly; 258 } 259 260 261 262 /** 263 * Creates a new restore task from the provided entry. 264 * 265 * @param entry The entry to use to create this restore task. 266 * 267 * @throws TaskException If the provided entry cannot be parsed as a restore 268 * task entry. 269 */ 270 public RestoreTask(final Entry entry) 271 throws TaskException 272 { 273 super(entry); 274 275 276 // Get the backup directory. It must be present. 277 backupDirectory = entry.getAttributeValue(ATTR_BACKUP_DIRECTORY); 278 if (backupDirectory == null) 279 { 280 throw new TaskException(ERR_RESTORE_NO_BACKUP_DIRECTORY.get( 281 getTaskEntryDN())); 282 } 283 284 285 // Get the backup ID. It may be absent. 286 backupID = entry.getAttributeValue(ATTR_BACKUP_ID); 287 288 289 // Get the verifyOnly flag. It may be absent. 290 verifyOnly = parseBooleanValue(entry, ATTR_VERIFY_ONLY, false); 291 } 292 293 294 295 /** 296 * Creates a new restore task from the provided set of task properties. 297 * 298 * @param properties The set of task properties and their corresponding 299 * values to use for the task. It must not be 300 * {@code null}. 301 * 302 * @throws TaskException If the provided set of properties cannot be used to 303 * create a valid restore task. 304 */ 305 public RestoreTask(final Map<TaskProperty,List<Object>> properties) 306 throws TaskException 307 { 308 super(RESTORE_TASK_CLASS, properties); 309 310 boolean v = false; 311 String b = null; 312 String i = null; 313 314 for (final Map.Entry<TaskProperty,List<Object>> entry : 315 properties.entrySet()) 316 { 317 final TaskProperty p = entry.getKey(); 318 final String attrName = p.getAttributeName(); 319 final List<Object> values = entry.getValue(); 320 321 if (attrName.equalsIgnoreCase(ATTR_BACKUP_DIRECTORY)) 322 { 323 b = parseString(p, values, b); 324 } 325 else if (attrName.equalsIgnoreCase(ATTR_BACKUP_ID)) 326 { 327 i = parseString(p, values, i); 328 } 329 else if (attrName.equalsIgnoreCase(ATTR_VERIFY_ONLY)) 330 { 331 v = parseBoolean(p, values, v); 332 } 333 } 334 335 if (b == null) 336 { 337 throw new TaskException(ERR_RESTORE_NO_BACKUP_DIRECTORY.get( 338 getTaskEntryDN())); 339 } 340 341 backupDirectory = b; 342 backupID = i; 343 verifyOnly = v; 344 } 345 346 347 348 /** 349 * {@inheritDoc} 350 */ 351 @Override() 352 public String getTaskName() 353 { 354 return INFO_TASK_NAME_RESTORE.get(); 355 } 356 357 358 359 /** 360 * {@inheritDoc} 361 */ 362 @Override() 363 public String getTaskDescription() 364 { 365 return INFO_TASK_DESCRIPTION_RESTORE.get(); 366 } 367 368 369 370 /** 371 * Retrieves the path to the backup directory which contains the backup to 372 * restore. It may be either an absolute path or one that is relative to the 373 * server root. 374 * 375 * @return The path to the backup directory which contains the backup to 376 * restore. 377 */ 378 public String getBackupDirectory() 379 { 380 return backupDirectory; 381 } 382 383 384 385 /** 386 * Retrieves the backup ID of the backup to restore. 387 * 388 * @return The backup ID of the backup to restore, or {@code null} if the 389 * most recent backup in the backup directory should be restored. 390 */ 391 public String getBackupID() 392 { 393 return backupID; 394 } 395 396 397 398 /** 399 * Indicates whether the backup should only be verified without actually being 400 * restored. 401 * 402 * @return {@code true} if the backup should be verified but not restored, or 403 * {@code false} if it should be restored. 404 */ 405 public boolean verifyOnly() 406 { 407 return verifyOnly; 408 } 409 410 411 412 /** 413 * {@inheritDoc} 414 */ 415 @Override() 416 protected List<String> getAdditionalObjectClasses() 417 { 418 return Arrays.asList(OC_RESTORE_TASK); 419 } 420 421 422 423 /** 424 * {@inheritDoc} 425 */ 426 @Override() 427 protected List<Attribute> getAdditionalAttributes() 428 { 429 final ArrayList<Attribute> attrs = new ArrayList<Attribute>(3); 430 431 attrs.add(new Attribute(ATTR_BACKUP_DIRECTORY, backupDirectory)); 432 attrs.add(new Attribute(ATTR_VERIFY_ONLY, String.valueOf(verifyOnly))); 433 434 if (backupID != null) 435 { 436 attrs.add(new Attribute(ATTR_BACKUP_ID, backupID)); 437 } 438 439 return attrs; 440 } 441 442 443 444 /** 445 * {@inheritDoc} 446 */ 447 @Override() 448 public List<TaskProperty> getTaskSpecificProperties() 449 { 450 final List<TaskProperty> propList = Arrays.asList( 451 PROPERTY_BACKUP_DIRECTORY, 452 PROPERTY_BACKUP_ID, 453 PROPERTY_VERIFY_ONLY); 454 455 return Collections.unmodifiableList(propList); 456 } 457 458 459 460 /** 461 * {@inheritDoc} 462 */ 463 @Override() 464 public Map<TaskProperty,List<Object>> getTaskPropertyValues() 465 { 466 final LinkedHashMap<TaskProperty,List<Object>> props = 467 new LinkedHashMap<TaskProperty,List<Object>>(); 468 469 props.put(PROPERTY_BACKUP_DIRECTORY, 470 Collections.<Object>unmodifiableList(Arrays.asList(backupDirectory))); 471 472 if (backupID == null) 473 { 474 props.put(PROPERTY_BACKUP_ID, Collections.emptyList()); 475 } 476 else 477 { 478 props.put(PROPERTY_BACKUP_ID, 479 Collections.<Object>unmodifiableList(Arrays.asList(backupID))); 480 } 481 482 props.put(PROPERTY_VERIFY_ONLY, 483 Collections.<Object>unmodifiableList(Arrays.asList(verifyOnly))); 484 485 props.putAll(super.getTaskPropertyValues()); 486 return Collections.unmodifiableMap(props); 487 } 488}