/// <summary> /// Add a full backup folder to the chain. /// </summary> /// <param name="backupFolder">Path of the input full backup folder.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>Task that represents the asynchronous work.</returns> /// <exception cref="ArgumentException">The relevant folder is not a valid full backup folder.</exception> /// <exception cref="InvalidDataException">There is a corruption in the file.</exception> private async Task AddFullBackupFolderAsync(string backupFolder, CancellationToken cancellationToken) { Utility.Assert(this.StateManagerBackupFolderPath == null, "There can only be one full backup."); Utility.Assert(FabricDirectory.Exists(backupFolder), "Directory must exist."); var stateManagerBackupFolderPath = Path.Combine(backupFolder, Replicator.Constants.StateManagerBackupFolderName); if (false == FabricDirectory.Exists(stateManagerBackupFolderPath)) { throw new ArgumentException(SR.Error_BackupFolderInfo_NullFolder, "backupFolder"); } this.fullBackupFolderPath = backupFolder; this.stateManagerBackupFolderPath = stateManagerBackupFolderPath; var metadataPath = Path.Combine(backupFolder, Replicator.Constants.ReplicatorBackupMetadataFileName); // Can throw InvalidDataException BackupMetadataFile backupMetadataFile; try { backupMetadataFile = await BackupMetadataFile.OpenAsync(metadataPath, cancellationToken).ConfigureAwait(false); } catch (Exception e) { FabricEvents.Events.RestoreException( this.traceType, Guid.Empty, e.GetType().ToString(), e.Message, e.StackTrace); throw; } var version = new BackupInfo.BackupVersion( backupMetadataFile.BackupEpoch, backupMetadataFile.BackupLsn); this.backupVersionList.Add(version); this.backupMetadataFileList.Add(backupMetadataFile); var logFolderPath = Path.Combine( backupFolder, Replicator.Constants.ReplicatorBackupFolderName, Replicator.Constants.ReplicatorBackupLogName); this.logFileList.Add(logFolderPath); }
/// <summary> /// Add an incremental backup folder to the chain. /// </summary> /// <param name="backupFolder">Path of the input full backup folder.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>Task that represents the asynchronous work.</returns> /// <exception cref="InvalidDataException">There is a corruption in the file.</exception> private async Task AddIncrementalBackupFolderAsync(string backupFolder, CancellationToken cancellationToken) { Utility.Assert( this.StateManagerBackupFolderPath != null, "There must at least be one full backup. Full backup must be added first."); var metadataPath = Path.Combine(backupFolder, Replicator.Constants.ReplicatorIncrementalBackupMetadataFileName); // Can throw InvalidDataException BackupMetadataFile backupMetadataFile; try { backupMetadataFile = await BackupMetadataFile.OpenAsync(metadataPath, cancellationToken).ConfigureAwait(false); } catch (Exception e) { FabricEvents.Events.RestoreException( this.traceType, Guid.Empty, e.GetType().ToString(), e.Message, e.StackTrace); throw; } var version = new BackupInfo.BackupVersion( backupMetadataFile.BackupEpoch, backupMetadataFile.BackupLsn); // If item is found, the right position will be returned, otherwise, a negative number that // is the bitwise complement of the index of the next element which is larger than the item or, if there is no // larger element, the bitwise complement of list count. int pos = backupVersionList.BinarySearch(version); int insertPos = pos < 0 ? ~pos : pos; this.backupVersionList.Insert(insertPos, version); this.backupMetadataFileList.Insert(insertPos, backupMetadataFile); var backupLogFilePath = Path.Combine( backupFolder, Replicator.Constants.ReplicatorBackupFolderName, Replicator.Constants.ReplicatorBackupLogName); this.logFileList.Insert(insertPos, backupLogFilePath); }