mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

coulbeck
21.21.2006 bbb17d25fbd11aa9829ab590f985be7a98c7cd11
Shorten the backup and restore runTask() methods and eliminate some of the repeated code for error handling.  Add unit tests for the restore task.
1 files renamed
2 files modified
766 ■■■■ changed files
opends/src/server/org/opends/server/tasks/BackupTask.java 555 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tasks/RestoreTask.java 146 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestBackupAndRestore.java 65 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tasks/BackupTask.java
@@ -76,6 +76,7 @@
  // The task arguments.
  private boolean backUpAll;
  private boolean compress;
  private boolean encrypt;
@@ -84,9 +85,16 @@
  private boolean signHash;
  private List<String>  backendIDList;
  private String  backupID;
  private String  backupDirectory;
  private File    backupDirectory;
  private String  incrementalBase;
  /**
   * All the backend configuration entries defined in the server mapped
   * by their backend ID.
   */
  private Map<String,ConfigEntry> configEntries;
  private ArrayList<Backend> backendsToArchive;
  /**
   * {@inheritDoc}
@@ -162,21 +170,28 @@
    backupID = TaskUtils.getSingleValueString(attrList);
    attrList = taskEntry.getAttribute(typeBackupDirectory);
    backupDirectory = TaskUtils.getSingleValueString(attrList);
    String backupDirectoryPath = TaskUtils.getSingleValueString(attrList);
    backupDirectory = new File(backupDirectoryPath);
    if (! backupDirectory.isAbsolute())
    {
      backupDirectory =
           new File(DirectoryServer.getServerRoot(), backupDirectoryPath);
    }
    attrList = taskEntry.getAttribute(typeIncrementalBaseID);
    incrementalBase = TaskUtils.getSingleValueString(attrList);
    configEntries = TaskUtils.getBackendConfigEntries();
  }
  /**
   * {@inheritDoc}
   * Validate the task arguments and construct the list of backends to be
   * archived.
   * @return  true if the task arguments are valid.
   */
  protected TaskState runTask()
  private boolean argumentsAreValid()
  {
    assert debugEnter(CLASS_NAME, "runTask");
    // Make sure that either the backUpAll argument was provided or at least one
    // backend ID was given.  They are mutually exclusive.
    if (backUpAll)
@@ -188,7 +203,7 @@
                                    ATTR_TASK_BACKUP_BACKEND_ID);
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        return TaskState.STOPPED_BY_ERROR;
        return false;
      }
    }
    else if (backendIDList.isEmpty())
@@ -198,7 +213,7 @@
                                  ATTR_TASK_BACKUP_BACKEND_ID);
      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
               message, msgID);
      return TaskState.STOPPED_BY_ERROR;
      return false;
    }
@@ -223,7 +238,7 @@
                                    ATTR_TASK_BACKUP_INCREMENTAL);
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        return TaskState.STOPPED_BY_ERROR;
        return false;
      }
    }
@@ -238,42 +253,31 @@
                                  ATTR_TASK_BACKUP_HASH);
      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
               message, msgID);
      return TaskState.STOPPED_BY_ERROR;
      return false;
    }
    // Make sure that the backup directory exists.  If not, then create it.
    File backupDirFile = new File(backupDirectory);
    if (! backupDirFile.isAbsolute())
    {
      backupDirectory = DirectoryServer.getServerRoot() + File.separator +
                        backupDirectory;
      backupDirFile = new File(backupDirectory);
    }
    if (! backupDirFile.exists())
    if (! backupDirectory.exists())
    {
      try
      {
        backupDirFile.mkdirs();
        backupDirectory.mkdirs();
      }
      catch (Exception e)
      {
        int    msgID   = MSGID_BACKUPDB_CANNOT_CREATE_BACKUP_DIR;
        String message = getMessage(msgID, backupDirectory,
        String message = getMessage(msgID, backupDirectory.getPath(),
                                    stackTraceToSingleLineString(e));
        System.err.println(message);
        return TaskState.STOPPED_BY_ERROR;
        return false;
      }
    }
    Map<String,ConfigEntry> configEntries =
         TaskUtils.getBackendConfigEntries();
    int numBackends = configEntries.size();
    boolean multiple;
    ArrayList<Backend> backendsToArchive = new ArrayList<Backend>(numBackends);
    backendsToArchive = new ArrayList<Backend>(numBackends);
    if (backUpAll)
    {
@@ -285,10 +289,6 @@
          backendsToArchive.add(b);
        }
      }
      // We'll proceed as if we're backing up multiple backends in this case
      // even if there's just one.
      multiple = true;
    }
    else
    {
@@ -320,11 +320,8 @@
      // It is an error if any of the requested backends could not be used.
      if (backendsToArchive.size() != backendIDList.size())
      {
        return TaskState.STOPPED_BY_ERROR;
        return false;
      }
      // See if there are multiple backends to archive.
      multiple = (backendsToArchive.size() > 1);
    }
@@ -335,15 +332,131 @@
      String message = getMessage(msgID);
      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR, message,
               msgID);
      return TaskState.STOPPED_BY_ERROR;
      return false;
    }
    // Iterate through the backends to archive and back them up individually.
    boolean errorsEncountered = false;
    for (Backend b : backendsToArchive)
    return true;
  }
  /**
   * Archive a single backend, where the backend is known to support backups.
   * @param b The backend to be archived.
   * @param backupLocation The backup directory.
   * @return true if the backend was successfully archived.
   */
  private boolean backupBackend(Backend b, File backupLocation)
    {
      // Acquire a shared lock for this backend.
    // Get the config entry for this backend.
    ConfigEntry configEntry = configEntries.get(b.getBackendID());
    // If the directory doesn't exist, then create it.  If it does exist, then
    // see if it has a backup descriptor file.
    BackupDirectory backupDir;
    if (backupLocation.exists())
    {
      String descriptorPath = backupLocation.getPath() + File.separator +
                              BACKUP_DIRECTORY_DESCRIPTOR_FILE;
      File descriptorFile = new File(descriptorPath);
      if (descriptorFile.exists())
      {
        try
        {
          backupDir = BackupDirectory.readBackupDirectoryDescriptor(
               backupLocation.getPath());
        }
        catch (ConfigException ce)
        {
          int msgID   = MSGID_BACKUPDB_CANNOT_PARSE_BACKUP_DESCRIPTOR;
          String message = getMessage(msgID, descriptorPath, ce.getMessage());
          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                   message, msgID);
          return false;
        }
        catch (Exception e)
        {
          int msgID   = MSGID_BACKUPDB_CANNOT_PARSE_BACKUP_DESCRIPTOR;
          String message = getMessage(msgID, descriptorPath,
                                      stackTraceToSingleLineString(e));
          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                   message, msgID);
          return false;
        }
      }
      else
      {
        backupDir = new BackupDirectory(backupLocation.getPath(),
                                        configEntry.getDN());
      }
    }
    else
    {
      try
      {
        backupLocation.mkdirs();
      }
      catch (Exception e)
      {
        int msgID   = MSGID_BACKUPDB_CANNOT_CREATE_BACKUP_DIR;
        String message = getMessage(msgID, backupLocation.getPath(),
                                    stackTraceToSingleLineString(e));
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        return false;
      }
      backupDir = new BackupDirectory(backupLocation.getPath(),
                                      configEntry.getDN());
    }
    // Create a backup configuration.  All the backends are known
    // to support backups so there is
    BackupConfig backupConfig = new BackupConfig(backupDir, backupID,
                                                 incremental);
    backupConfig.setCompressData(compress);
    backupConfig.setEncryptData(encrypt);
    backupConfig.setHashData(hash);
    backupConfig.setSignHash(signHash);
    backupConfig.setIncrementalBaseID(incrementalBase);
    // Perform the backup.
    try
    {
      b.createBackup(configEntry, backupConfig);
    }
    catch (DirectoryException de)
    {
      int msgID   = MSGID_BACKUPDB_ERROR_DURING_BACKUP;
      String message = getMessage(msgID, b.getBackendID(),
                                  de.getErrorMessage());
      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
               message, msgID);
      return false;
    }
    catch (Exception e)
    {
      int msgID   = MSGID_BACKUPDB_ERROR_DURING_BACKUP;
      String message = getMessage(msgID, b.getBackendID(),
                                  stackTraceToSingleLineString(e));
      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
               message, msgID);
      return false;
    }
    return true;
  }
  /**
   * Acquire a shared lock on a backend.
   * @param b The backend on which the lock is to be acquired.
   * @return true if the lock was successfully acquired.
   */
  private boolean lockBackend(Backend b)
  {
      try
      {
        String        lockFile      = LockFileManager.getBackendLockFileName(b);
@@ -355,8 +468,7 @@
                                      String.valueOf(failureReason));
          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                   message, msgID);
          errorsEncountered = true;
          continue;
        return false;
        }
      }
      catch (Exception e)
@@ -366,311 +478,122 @@
                                    stackTraceToSingleLineString(e));
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
      return false;
    }
    return true;
  }
  /**
   * Release a lock on a backend.
   * @param b The backend on which the lock is held.
   * @return true if the lock was successfully released.
   */
  private boolean unlockBackend(Backend b)
  {
    try
    {
      String lockFile = LockFileManager.getBackendLockFileName(b);
      StringBuilder failureReason = new StringBuilder();
      if (! LockFileManager.releaseLock(lockFile, failureReason))
      {
        int msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
        String message = getMessage(msgID, b.getBackendID(),
                             String.valueOf(failureReason));
        logError(ErrorLogCategory.BACKEND,
                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
        return false;
      }
    }
    catch (Exception e)
    {
      int msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
      String message = getMessage(msgID, b.getBackendID(),
                                  stackTraceToSingleLineString(e));
      logError(ErrorLogCategory.BACKEND,
               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
      return false;
    }
    return true;
  }
  /**
   * {@inheritDoc}
   */
  protected TaskState runTask()
  {
    assert debugEnter(CLASS_NAME, "runTask");
    if (!argumentsAreValid())
    {
      return TaskState.STOPPED_BY_ERROR;
    }
    boolean multiple;
    if (backUpAll)
    {
      // We'll proceed as if we're backing up multiple backends in this case
      // even if there's just one.
      multiple = true;
    }
    else
    {
      // See if there are multiple backends to archive.
      multiple = (backendsToArchive.size() > 1);
    }
    // Iterate through the backends to archive and back them up individually.
    boolean errorsEncountered = false;
    for (Backend b : backendsToArchive)
    {
      // Acquire a shared lock for this backend.
      if (!lockBackend(b))
      {
        errorsEncountered = true;
        continue;
      }
      try
      {
      int    msgID = MSGID_BACKUPDB_STARTING_BACKUP;
      String message = getMessage(msgID, b.getBackendID());
      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.NOTICE, message,
               msgID);
      // Get the config entry for this backend.
      ConfigEntry configEntry = configEntries.get(b.getBackendID());
      // Get the path to the directory to use for this backup.  If we will be
      // backing up multiple backends (or if we are backing up all backends,
      // even if there's only one of them), then create a subdirectory for each
        // even if there's only one of them), then create a subdirectory for
        // each
      // backend.
      String backupDirPath;
        File backupLocation;
      if (multiple)
      {
        backupDirPath = backupDirectory + File.separator +
                        b.getBackendID();
          backupLocation = new File(backupDirectory, b.getBackendID());
      }
      else
      {
        backupDirPath = backupDirectory;
          backupLocation = backupDirectory;
      }
      // If the directory doesn't exist, then create it.  If it does exist, then
      // see if it has a backup descriptor file.
      BackupDirectory backupDir;
      backupDirFile = new File(backupDirPath);
      if (backupDirFile.exists())
        if (!backupBackend(b, backupLocation))
      {
        String descriptorPath = backupDirPath + File.separator +
                                BACKUP_DIRECTORY_DESCRIPTOR_FILE;
        File descriptorFile = new File(descriptorPath);
        if (descriptorFile.exists())
        {
          try
          {
            backupDir =
                 BackupDirectory.readBackupDirectoryDescriptor(backupDirPath);
          }
          catch (ConfigException ce)
          {
            msgID   = MSGID_BACKUPDB_CANNOT_PARSE_BACKUP_DESCRIPTOR;
            message = getMessage(msgID, descriptorPath, ce.getMessage());
            logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                     message, msgID);
            errorsEncountered = true;
            try
        }
      }
      finally
            {
              String lockFile = LockFileManager.getBackendLockFileName(b);
              StringBuilder failureReason = new StringBuilder();
              if (! LockFileManager.releaseLock(lockFile, failureReason))
              {
                msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
                message = getMessage(msgID, b.getBackendID(),
                                     String.valueOf(failureReason));
                logError(ErrorLogCategory.BACKEND,
                         ErrorLogSeverity.SEVERE_WARNING, message, msgID);
              }
            }
            catch (Exception e)
            {
              msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
              message = getMessage(msgID, b.getBackendID(),
                                   stackTraceToSingleLineString(e));
              logError(ErrorLogCategory.BACKEND,
                       ErrorLogSeverity.SEVERE_WARNING, message, msgID);
            }
            continue;
          }
          catch (Exception e)
          {
            msgID   = MSGID_BACKUPDB_CANNOT_PARSE_BACKUP_DESCRIPTOR;
            message = getMessage(msgID, descriptorPath,
                                 stackTraceToSingleLineString(e));
            logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                     message, msgID);
            errorsEncountered = true;
            try
            {
              String lockFile = LockFileManager.getBackendLockFileName(b);
              StringBuilder failureReason = new StringBuilder();
              if (! LockFileManager.releaseLock(lockFile, failureReason))
              {
                msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
                message = getMessage(msgID, b.getBackendID(),
                                     String.valueOf(failureReason));
                logError(ErrorLogCategory.BACKEND,
                         ErrorLogSeverity.SEVERE_WARNING, message, msgID);
              }
            }
            catch (Exception e2)
            {
              msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
              message = getMessage(msgID, b.getBackendID(),
                                   stackTraceToSingleLineString(e2));
              logError(ErrorLogCategory.BACKEND,
                       ErrorLogSeverity.SEVERE_WARNING, message, msgID);
            }
            continue;
          }
        }
        else
        {
          backupDir = new BackupDirectory(backupDirPath, configEntry.getDN());
        }
      }
      else
      {
        try
        {
          backupDirFile.mkdirs();
        }
        catch (Exception e)
        {
          msgID   = MSGID_BACKUPDB_CANNOT_CREATE_BACKUP_DIR;
          message = getMessage(msgID, backupDirPath,
                               stackTraceToSingleLineString(e));
          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                   message, msgID);
          errorsEncountered = true;
          try
          {
            String lockFile = LockFileManager.getBackendLockFileName(b);
            StringBuilder failureReason = new StringBuilder();
            if (! LockFileManager.releaseLock(lockFile, failureReason))
            {
              msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
              message = getMessage(msgID, b.getBackendID(),
                                   String.valueOf(failureReason));
              logError(ErrorLogCategory.BACKEND,
                       ErrorLogSeverity.SEVERE_WARNING, message, msgID);
            }
          }
          catch (Exception e2)
          {
            msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
            message = getMessage(msgID, b.getBackendID(),
                                 stackTraceToSingleLineString(e2));
            logError(ErrorLogCategory.BACKEND,
                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
          }
          continue;
        }
        backupDir = new BackupDirectory(backupDirPath, configEntry.getDN());
      }
      // Create a backup configuration and determine whether the requested
      // backup can be performed using the selected backend.
      BackupConfig backupConfig = new BackupConfig(backupDir, backupID,
                                                   incremental);
      backupConfig.setCompressData(compress);
      backupConfig.setEncryptData(encrypt);
      backupConfig.setHashData(hash);
      backupConfig.setSignHash(signHash);
      backupConfig.setIncrementalBaseID(incrementalBase);
      StringBuilder unsupportedReason = new StringBuilder();
      if (! b.supportsBackup(backupConfig, unsupportedReason))
      {
        msgID   = MSGID_BACKUPDB_CANNOT_BACKUP;
        message = getMessage(msgID, b.getBackendID(),
                             unsupportedReason.toString());
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        errorsEncountered = true;
        try
        {
          String lockFile = LockFileManager.getBackendLockFileName(b);
          StringBuilder failureReason = new StringBuilder();
          if (! LockFileManager.releaseLock(lockFile, failureReason))
          {
            msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
            message = getMessage(msgID, b.getBackendID(),
                                 String.valueOf(failureReason));
            logError(ErrorLogCategory.BACKEND,
                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
          }
        }
        catch (Exception e2)
        {
          msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
          message = getMessage(msgID, b.getBackendID(),
                               stackTraceToSingleLineString(e2));
          logError(ErrorLogCategory.BACKEND,
                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
        }
        continue;
      }
      // Perform the backup.
      try
      {
        b.createBackup(configEntry, backupConfig);
      }
      catch (DirectoryException de)
      {
        msgID   = MSGID_BACKUPDB_ERROR_DURING_BACKUP;
        message = getMessage(msgID, b.getBackendID(),
                                    de.getErrorMessage());
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        errorsEncountered = true;
        try
        {
          String lockFile = LockFileManager.getBackendLockFileName(b);
          StringBuilder failureReason = new StringBuilder();
          if (! LockFileManager.releaseLock(lockFile, failureReason))
          {
            msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
            message = getMessage(msgID, b.getBackendID(),
                                 String.valueOf(failureReason));
            logError(ErrorLogCategory.BACKEND,
                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
          }
        }
        catch (Exception e)
        {
          msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
          message = getMessage(msgID, b.getBackendID(),
                               stackTraceToSingleLineString(e));
          logError(ErrorLogCategory.BACKEND,
                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
        }
        continue;
      }
      catch (Exception e)
      {
        msgID   = MSGID_BACKUPDB_ERROR_DURING_BACKUP;
        message = getMessage(msgID, b.getBackendID(),
                                    stackTraceToSingleLineString(e));
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        errorsEncountered = true;
        try
        {
          String lockFile = LockFileManager.getBackendLockFileName(b);
          StringBuilder failureReason = new StringBuilder();
          if (! LockFileManager.releaseLock(lockFile, failureReason))
          {
            msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
            message = getMessage(msgID, b.getBackendID(),
                                 String.valueOf(failureReason));
            logError(ErrorLogCategory.BACKEND,
                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
          }
        }
        catch (Exception e2)
        {
          msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
          message = getMessage(msgID, b.getBackendID(),
                               stackTraceToSingleLineString(e2));
          logError(ErrorLogCategory.BACKEND,
                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
        }
        continue;
      }
      // Release the shared lock for the backend.
      try
        if (!unlockBackend(b))
      {
        String lockFile = LockFileManager.getBackendLockFileName(b);
        StringBuilder failureReason = new StringBuilder();
        if (! LockFileManager.releaseLock(lockFile, failureReason))
        {
          msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
          message = getMessage(msgID, b.getBackendID(),
                               String.valueOf(failureReason));
          logError(ErrorLogCategory.BACKEND,
                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
          errorsEncountered = true;
        }
      }
      catch (Exception e)
      {
        msgID   = MSGID_BACKUPDB_CANNOT_UNLOCK_BACKEND;
        message = getMessage(msgID, b.getBackendID(),
                             stackTraceToSingleLineString(e));
        logError(ErrorLogCategory.BACKEND,
                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
        errorsEncountered = true;
      }
    }
opends/src/server/org/opends/server/tasks/RestoreTask.java
@@ -54,6 +54,7 @@
import org.opends.server.types.RestoreConfig;
import java.util.List;
import java.io.File;
/**
 * This class provides an implementation of a Directory Server task that can
@@ -69,7 +70,8 @@
  private String backupDirectory;
  // The task arguments.
  private File backupDirectory;
  private String backupID;
  private boolean verifyOnly;
@@ -99,7 +101,13 @@
    List<Attribute> attrList;
    attrList = taskEntry.getAttribute(typeBackupDirectory);
    backupDirectory = TaskUtils.getSingleValueString(attrList);
    String backupDirectoryPath = TaskUtils.getSingleValueString(attrList);
    backupDirectory = new File(backupDirectoryPath);
    if (! backupDirectory.isAbsolute())
    {
      backupDirectory =
           new File(DirectoryServer.getServerRoot(), backupDirectoryPath);
    }
    attrList = taskEntry.getAttribute(typebackupID);
    backupID = TaskUtils.getSingleValueString(attrList);
@@ -110,6 +118,72 @@
  }
  /**
   * Acquire an exclusive lock on a backend.
   * @param backend The backend on which the lock is to be acquired.
   * @return true if the lock was successfully acquired.
   */
  private boolean lockBackend(Backend backend)
  {
    try
    {
      String lockFile = LockFileManager.getBackendLockFileName(backend);
      StringBuilder failureReason = new StringBuilder();
      if (! LockFileManager.acquireExclusiveLock(lockFile, failureReason))
      {
        int    msgID   = MSGID_RESTOREDB_CANNOT_LOCK_BACKEND;
        String message = getMessage(msgID, backend.getBackendID(),
                                    String.valueOf(failureReason));
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        return false;
      }
    }
    catch (Exception e)
    {
      int    msgID   = MSGID_RESTOREDB_CANNOT_LOCK_BACKEND;
      String message = getMessage(msgID, backend.getBackendID(),
                                  stackTraceToSingleLineString(e));
      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
               message, msgID);
      return false;
    }
    return true;
  }
  /**
   * Release a lock on a backend.
   * @param backend The backend on which the lock is held.
   * @return true if the lock was successfully released.
   */
  private boolean unlockBackend(Backend backend)
  {
    try
    {
      String lockFile = LockFileManager.getBackendLockFileName(backend);
      StringBuilder failureReason = new StringBuilder();
      if (! LockFileManager.releaseLock(lockFile, failureReason))
      {
        int    msgID   = MSGID_RESTOREDB_CANNOT_UNLOCK_BACKEND;
        String message = getMessage(msgID, backend.getBackendID(),
                                    String.valueOf(failureReason));
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_WARNING,
                 message, msgID);
        return false;
      }
    }
    catch (Exception e)
    {
      int    msgID   = MSGID_RESTOREDB_CANNOT_UNLOCK_BACKEND;
      String message = getMessage(msgID, backend.getBackendID(),
                                  stackTraceToSingleLineString(e));
      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_WARNING,
               message, msgID);
      return false;
    }
    return true;
  }
  /**
   * {@inheritDoc}
   */
  protected TaskState runTask()
@@ -117,11 +191,11 @@
    assert debugEnter(CLASS_NAME, "runTask");
    // Open the backup directory and make sure it is valid.
    BackupDirectory backupDir = null;
    BackupDirectory backupDir;
    try
    {
      backupDir =
           BackupDirectory.readBackupDirectoryDescriptor(backupDirectory);
      backupDir = BackupDirectory.readBackupDirectoryDescriptor(
           backupDirectory.getPath());
    }
    catch (Exception e)
    {
@@ -221,34 +295,12 @@
    // From here we must make sure to re-enable the backend before returning.
    boolean errorsEncountered = false;
    try
    {
      // Acquire an exclusive lock for the backend.
      try
      if (lockBackend(backend))
      {
        String lockFile = LockFileManager.getBackendLockFileName(backend);
        StringBuilder failureReason = new StringBuilder();
        if (! LockFileManager.acquireExclusiveLock(lockFile, failureReason))
        {
          int    msgID   = MSGID_RESTOREDB_CANNOT_LOCK_BACKEND;
          String message = getMessage(msgID, backend.getBackendID(),
                                      String.valueOf(failureReason));
          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                   message, msgID);
          return TaskState.STOPPED_BY_ERROR;
        }
      }
      catch (Exception e)
      {
        int    msgID   = MSGID_RESTOREDB_CANNOT_LOCK_BACKEND;
        String message = getMessage(msgID, backend.getBackendID(),
                                    stackTraceToSingleLineString(e));
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        return TaskState.STOPPED_BY_ERROR;
      }
      // From here we must make sure to release the backend exclusive lock.
      try
      {
@@ -264,7 +316,7 @@
                                      de.getErrorMessage());
          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                   message, msgID);
          return TaskState.STOPPED_BY_ERROR;
            errorsEncountered = true;
        }
        catch (Exception e)
        {
@@ -273,38 +325,19 @@
                                      stackTraceToSingleLineString(e));
          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                   message, msgID);
          return TaskState.STOPPED_BY_ERROR;
            errorsEncountered = true;
        }
      }
      finally
      {
        // Release the exclusive lock on the backend.
        try
          if (!unlockBackend(backend))
        {
          String lockFile = LockFileManager.getBackendLockFileName(backend);
          StringBuilder failureReason = new StringBuilder();
          if (! LockFileManager.releaseLock(lockFile, failureReason))
          {
            int    msgID   = MSGID_RESTOREDB_CANNOT_UNLOCK_BACKEND;
            String message = getMessage(msgID, backend.getBackendID(),
                                        String.valueOf(failureReason));
            logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_WARNING,
                     message, msgID);
            return TaskState.COMPLETED_WITH_ERRORS;
            errorsEncountered = true;
          }
        }
        catch (Exception e)
        {
          int    msgID   = MSGID_RESTOREDB_CANNOT_UNLOCK_BACKEND;
          String message = getMessage(msgID, backend.getBackendID(),
                                      stackTraceToSingleLineString(e));
          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_WARNING,
                   message, msgID);
          return TaskState.COMPLETED_WITH_ERRORS;
        }
      }
    }
    finally
    {
      // Enable the backend.
@@ -318,10 +351,17 @@
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 e.getErrorMessage(), e.getErrorMessageID());
        return TaskState.STOPPED_BY_ERROR;
        errorsEncountered = true;
      }
    }
    if (errorsEncountered)
    {
      return TaskState.COMPLETED_WITH_ERRORS;
    }
    else
    {
    return TaskState.COMPLETED_SUCCESSFULLY;
  }
}
}
opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestBackupAndRestore.java
File was renamed from opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestBackupTaskArguments.java
@@ -36,11 +36,12 @@
import org.opends.server.TestCaseUtils;
import java.util.UUID;
import java.io.File;
/**
 * Tests various valid and invalid combinations of arguments to the backup task.
 * Tests the backup and restore tasks.
 */
public class TestBackupTaskArguments extends TasksTestCase
public class TestBackupAndRestore extends TasksTestCase
{
  @BeforeClass
  public final void setUp() throws Exception {
@@ -49,7 +50,7 @@
  /**
   * Backup tasks test data provider.
   * Backup and restore tasks test data provider.
   *
   * @return The array of tasks test data.  The first column is a task entry
   *  and the second column is the expected completed task state.
@@ -158,13 +159,69 @@
                   "ds-task-backup-backend-id: monitor"),
              TaskState.STOPPED_BY_ERROR
         },
         {
              // A valid restore task.
              TestCaseUtils.makeEntry(
                   "dn: ds-task-id=" + UUID.randomUUID() +
                        ",cn=Scheduled Tasks,cn=Tasks",
                   "objectclass: top",
                   "objectclass: ds-task",
                   "objectclass: ds-task-restore",
                   "ds-task-class-name: org.opends.server.tasks.RestoreTask",
                   "ds-backup-directory-path: bak" + File.separator +
                        "userRoot"
              ),
              TaskState.COMPLETED_SUCCESSFULLY
         },
         {
              // Non-existent restore directory-path.
              TestCaseUtils.makeEntry(
                   "dn: ds-task-id=" + UUID.randomUUID() +
                        ",cn=Scheduled Tasks,cn=Tasks",
                   "objectclass: top",
                   "objectclass: ds-task",
                   "objectclass: ds-task-restore",
                   "ds-task-class-name: org.opends.server.tasks.RestoreTask",
                   "ds-backup-directory-path: missing"
              ),
              TaskState.STOPPED_BY_ERROR
         },
         {
              // Invalid restore directory-path.
              TestCaseUtils.makeEntry(
                   "dn: ds-task-id=" + UUID.randomUUID() +
                        ",cn=Scheduled Tasks,cn=Tasks",
                   "objectclass: top",
                   "objectclass: ds-task",
                   "objectclass: ds-task-restore",
                   "ds-task-class-name: org.opends.server.tasks.RestoreTask",
                   "ds-backup-directory-path: bak"
              ),
              TaskState.STOPPED_BY_ERROR
         },
         {
              // Invalid restore backup-id.
              TestCaseUtils.makeEntry(
                   "dn: ds-task-id=" + UUID.randomUUID() +
                        ",cn=Scheduled Tasks,cn=Tasks",
                   "objectclass: top",
                   "objectclass: ds-task",
                   "objectclass: ds-task-restore",
                   "ds-task-class-name: org.opends.server.tasks.RestoreTask",
                   "ds-backup-directory-path: bak" + File.separator +
                        "userRoot",
                   "ds-backup-id: monday"
              ),
              TaskState.STOPPED_BY_ERROR
         },
    };
  }
  /**
   * Test that various backup task definitions complete with the expected state.
   * Test that various backup and restore task definitions complete with the
   * expected state.
   * @param taskEntry The task entry.
   * @param expectedState The expected completion state of the task.
   */