internal async override Task InitializeAsync() { await base.InitializeAsync(); this.RestoreStore = await RestoreStore.CreateOrGetRestoreStatusStore(this.StatefulService).ConfigureAwait(false); this.BackupPartitionStore = await BackupPartitionStore.CreateOrGetBackupPartitionStore(this.StatefulService).ConfigureAwait(false); }
public async Task RestoreOperationResultAsync(RestoreOperationResult operationResult, TimeSpan timeout, CancellationToken cancellationToken) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "RestoreOperationResultAsync invoked for partition {0}, ErrorCode {1}, message {2}", operationResult.PartitionId, operationResult.ErrorCode, operationResult.Message); var restoreStore = await RestoreStore.CreateOrGetRestoreStatusStore(this.statefulService); var workItemQueue = await WorkItemQueue.CreateOrGetWorkItemQueue(this.statefulService); string brsServiceUri = await UtilityHelper.GetCustomServiceUri(operationResult.ServiceName, timeout, cancellationToken); var fabricUri = UtilityHelper.GetBackupMappingKey(brsServiceUri, operationResult.PartitionId.ToString()); WorkItem pushPolicyAfterRestore = new SendToServiceNodeWorkItem(brsServiceUri, operationResult.PartitionId.ToString(), new WorkItemInfo() { WorkItemType = WorkItemPropogationType.UpdatePolicyAfterRestore, }); await UtilityHelper.InvokeWithRetry(async() => { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Trying to Update the Restore request for partition {0}", operationResult.PartitionId); using (ITransaction transaction = this.statefulService.StateManager.CreateTransaction()) { var restoreStatus = await restoreStore.GetValueWithUpdateLockModeAsync(fabricUri, timeout, cancellationToken, transaction); if ((restoreStatus != null) && (restoreStatus.RestoreStatusState == RestoreState.RestoreInProgress || restoreStatus.RestoreStatusState == RestoreState.Accepted) && (restoreStatus.RestoreRequestGuid.Equals(operationResult.OperationId))) //TODO: Add check for each request by Guid { var updatedRestoreStatus = restoreStatus.ToBuilder() .WithState(operationResult.ErrorCode != 0 ? RestoreState.Failure : RestoreState.Success) .WithErrorCode(operationResult.ErrorCode) .WithMessage(operationResult.Message) .WithTimeStampUtc(operationResult.TimeStampUtc) .Build(); await restoreStore.UpdateValueAsync(fabricUri, updatedRestoreStatus, timeout, cancellationToken, transaction); await workItemQueue.AddWorkItem(pushPolicyAfterRestore, timeout, cancellationToken, transaction); await transaction.CommitAsync(); BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Updated the Restore request for partition {0}", operationResult.PartitionId); } else { transaction.Abort(); } } }); }
public async Task <RestorePointDetails> GetRestorePointDetailsAsync(BackupPartitionInfo backupPartitionInfo, TimeSpan timeout, CancellationToken cancellationToken) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "GetRestorePointDetailsAsync invoked for partition {0}", backupPartitionInfo.PartitionId); var restoreStore = await RestoreStore.CreateOrGetRestoreStatusStore(this.statefulService); var backupMappingStore = await BackupMappingStore.CreateOrGetBackupMappingStore(this.statefulService); var backupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.statefulService); bool userInitiatedOperation; BackupStorage backupStorage; BackupStoreInformation backupStoreInformation = null; List <string> backupLocations; string brsServiceUri = await UtilityHelper.GetCustomServiceUri(backupPartitionInfo.ServiceName, timeout, cancellationToken); var fabricUri = UtilityHelper.GetBackupMappingKey(brsServiceUri, backupPartitionInfo.PartitionId.ToString()); var restoreStatus = await restoreStore.GetValueAsync(fabricUri); if (restoreStatus != null && ( restoreStatus.RestoreStatusState != RestoreState.Failure || restoreStatus.RestoreStatusState != RestoreState.Invalid || restoreStatus.RestoreStatusState != RestoreState.Success || restoreStatus.RestoreStatusState != RestoreState.Timeout)) { backupStorage = restoreStatus.BackupStorage; userInitiatedOperation = true; backupLocations = restoreStatus.BackupLocations.ToList(); } else { var backupMappingKey = UtilityHelper.GetBackupMappingKey(brsServiceUri, backupPartitionInfo.PartitionId.ToString()); var backupMappingModel = (await backupMappingStore.GetValueAsync(backupMappingKey) ?? await backupMappingStore.GetValueAsync(brsServiceUri)) ?? await backupMappingStore.GetValueAsync(UtilityHelper.GetApplicationNameFromService(brsServiceUri)); if (backupMappingModel == null) { throw new FabricPeriodicBackupNotEnabledException(); } var backupPolicy = await backupPolicyStore.GetValueAsync(backupMappingModel.BackupPolicyName); if (backupPolicy != null && backupPolicy.AutoRestore) { backupStorage = backupPolicy.Storage; userInitiatedOperation = false; string applicationName, serviceName; UtilityHelper.GetApplicationAndServiceNameFromServiceUri(brsServiceUri, out applicationName, out serviceName); // Get the latest backup now var backups = await backupStorage.GetBackupEnumerationsTask( applicationName, serviceName, backupPartitionInfo.PartitionId.ToString(), DateTime.MinValue, DateTime.MaxValue, true, cancellationToken); if (backups == null || backups.Count == 0) { throw new ArgumentException(); // TODO: Change this with appropriate exception } var backupDetail = backups.First(); var recoveryPointManager = RecoveryPointManagerFactory.GetRecoveryPointManager(backupStorage); backupLocations = await recoveryPointManager.GetBackupLocationsInBackupChainAsync(backupDetail.BackupLocation, cancellationToken); } else { throw new ArgumentException(); // TODO: Change with the OTher exception } } switch (backupStorage.BackupStorageType) { case BackupStorageType.FileShare: var fileShareStorage = (FileShareStorage)backupStorage; backupStoreInformation = new FileShareBackupStore { AccessType = String.IsNullOrEmpty(fileShareStorage.PrimaryUserName) ? FileShareAccessType.None : FileShareAccessType.DomainUser, FileSharePath = fileShareStorage.Path, PrimaryUserName = fileShareStorage.PrimaryUserName, PrimaryPassword = fileShareStorage.PrimaryPassword, SecondaryUserName = fileShareStorage.SecondaryUserName, SecondaryPassword = fileShareStorage.SecondaryPassword, IsPasswordEncrypted = fileShareStorage.IsPasswordEncrypted, }; break; case BackupStorageType.AzureBlobStore: var azureStorage = (AzureStorage)backupStorage; backupStoreInformation = new AzureBlobBackupStore { ConnectionString = azureStorage.ConnectionString, ContainerName = azureStorage.ContainerName, FolderPath = String.Empty, // TODO: This should be constructed IsAccountKeyEncrypted = azureStorage.IsConnectionStringEncrypted, }; break; case BackupStorageType.DsmsAzureBlobStore: var dsmsAzureStorage = (DsmsAzureStorage)backupStorage; backupStoreInformation = new DsmsAzureBlobBackupStore { StorageCredentialsSourceLocation = dsmsAzureStorage.StorageCredentialsSourceLocation, ContainerName = dsmsAzureStorage.ContainerName, FolderPath = String.Empty, // TODO: This should be constructed }; break; } Guid restoreOperationId = Guid.NewGuid(); if (userInitiatedOperation) { await UtilityHelper.InvokeWithRetry(async() => { using (ITransaction transaction = this.statefulService.StateManager.CreateTransaction()) { var currentRestoreStatus = await restoreStore.GetValueWithUpdateLockModeAsync(fabricUri, timeout, cancellationToken, transaction); restoreOperationId = currentRestoreStatus.RestoreRequestGuid; if (currentRestoreStatus.RestoreStatusState == RestoreState.Accepted) //TODO Check for Guid { var toUpdateRestoreStatus = currentRestoreStatus.ToBuilder().WithState(RestoreState.RestoreInProgress).Build(); await restoreStore.UpdateValueAsync(fabricUri, toUpdateRestoreStatus, timeout, cancellationToken, transaction); await transaction.CommitAsync(); } else { transaction.Abort(); } } }); } var restorePartitionDetails = new RestorePointDetails() { BackupLocations = backupLocations, UserInitiatedOperation = userInitiatedOperation, StoreInformation = backupStoreInformation, OperationId = restoreOperationId }; BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "GetRestorePointDetailsAsync invoked for partition {0} with Return Values {1}", backupPartitionInfo.PartitionId, restorePartitionDetails); return(restorePartitionDetails); }