/// <summary> /// Gets called when a partition is disabled for a pariticular policy. /// </summary> internal async Task DisablePolicyAsync(BackupPolicy backupPolicy, string partitionId, BackupMapping inheritedBackupMapping, TimeSpan timeout, CancellationToken cancellationToken, ITransaction transaction) { /** * Cases: * 1. Partition has different policy inherited and storage is different, cleanup wont impact the same storage. * ---> Check whether the timercallback is finished or not. * 2. Partition has different inherited policy and storage and container are same. * --> NO Cleanup * **/ // Since, you have disabled the policy now look for the backup mapping on the partition. var backupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.StatefulService); if (inheritedBackupMapping == null) { await AddPartitionToCleanUpStore(partitionId, backupPolicy, cancellationToken, transaction); Task cleanUpTask = CleanUpTaskUtil(partitionId, backupPolicy); } else { var inheritedPolicy = await backupPolicyStore.GetValueAsync(inheritedBackupMapping.BackupPolicyName); if (!backupPolicy.Storage.CompareStorage(inheritedPolicy.Storage)) { BackupRestoreTrace.TraceSource.WriteWarning(TraceType, "Inherited Policy for partition:{0} is having same storage, so, cleanup is skipped."); } else { await AddPartitionToCleanUpStore(partitionId, backupPolicy, cancellationToken, transaction); Task cleanUpTask = CleanUpTaskUtil(partitionId, backupPolicy); } } }
internal async override Task InitializeAsync() { this.BackupMappingStore = await BackupMappingStore.CreateOrGetBackupMappingStore(this.StatefulService).ConfigureAwait(false); this.BackupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.StatefulService).ConfigureAwait(false); this.WorkItemQueue = await WorkItemQueue.CreateOrGetWorkItemQueue(this.StatefulService).ConfigureAwait(false); }
private async Task UpdateSecretsAsync(string thumbprintFromManifest, string x509StoreNameFromManifest, CancellationToken cancellationToken) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, String.Format("Updating secrets using the new thumbprint {0}", thumbprintFromManifest)); using (var transaction = this.StateManager.CreateTransaction()) { try { var policyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this); var workItemQueue = await WorkItemQueue.CreateOrGetWorkItemQueue(this); var policies = await policyStore.GetValuesAsync(Common.Constants.StoreTimeOut, cancellationToken, transaction); foreach (var policy in policies) { cancellationToken.ThrowIfCancellationRequested(); var updatedStorage = this.UpdateSecretInStorage(policy.Storage, thumbprintFromManifest, x509StoreNameFromManifest, cancellationToken); var newPolicy = policy.ToBuilder() .WithBackupStorage(updatedStorage) .UpdateUniqueId() .Build(); if (!await policyStore.UpdateValueAsync(policy.Name, policy, newPolicy, Common.Constants.StoreTimeOut, cancellationToken, transaction)) { throw new InvalidOperationException(String.Format("Failed to update secret for policy with name {0}", newPolicy.Name)); } if (newPolicy.BackupEnabledSet.Count > 0) { await workItemQueue.AddWorkItem( new UpdateEnablementWorkItem(newPolicy.BackupEnabledSet.ToList(), new WorkItemInfo { WorkItemType = WorkItemPropogationType.UpdateBackupPolicy, BackupPolicyUpdateGuid = newPolicy.UniqueId }), Common.Constants.StoreTimeOut, cancellationToken, transaction); } } // Update the config store var configStore = await ConfigStore.CreateOrGetConfigStore(this); await configStore.UpdateValueAsync(Common.Constants.SecretUpdateInProgress, String.Empty, Common.Constants.StoreTimeOut, cancellationToken, transaction); await configStore.UpdateValueAsync(Common.Constants.EncryptionCertThumbprintKey, thumbprintFromManifest, Common.Constants.StoreTimeOut, cancellationToken, transaction); await transaction.CommitAsync(); BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "All secrets updated with manifest {0}", thumbprintFromManifest); FabricEvents.Events.BRSSecretsUpdated(TraceType, thumbprintFromManifest); } catch (Exception ex) { BackupRestoreTrace.TraceSource.WriteExceptionAsWarning(TraceType, ex, "Exception encountered while updating secrets"); throw; } } }
internal async Task DisablePolicyAsync(string fabricUri, BackupMapping currentBackupMapping, TimeSpan timeout, CancellationToken cancellationToken, ITransaction transaction) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, " In DisablePolicyAsync for fabricUri : {0}", fabricUri); string applicationNameUri = null; string serviceNameUri = null; string partitionID = null; var fabricBackupResourceType = UtilityHelper.GetApplicationAndServicePartitionUri(fabricUri, out applicationNameUri, out serviceNameUri, out partitionID); List <string> filteredPartitionList = new List <string>(); var backupMappingStore = await BackupMappingStore.CreateOrGetBackupMappingStore(this.StatefulService); var backupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.StatefulService); var currentBackupPolicy = await backupPolicyStore.GetValueAsync(currentBackupMapping.BackupPolicyName, transaction); BackupMapping inheritedBackupMapping = null; switch (fabricBackupResourceType) { case FabricBackupResourceType.ApplicationUri: filteredPartitionList = await FilterPartitionListToDisableForFabricURI(await GetPartitionsForServiceOrApplication(fabricUri, FabricBackupResourceType.ApplicationUri, timeout, cancellationToken), timeout, cancellationToken, FabricBackupResourceType.ServiceUri); break; case FabricBackupResourceType.ServiceUri: filteredPartitionList = await FilterPartitionListToDisableForFabricURI(await GetPartitionsForServiceOrApplication(fabricUri, FabricBackupResourceType.ServiceUri, timeout, cancellationToken), timeout, cancellationToken, FabricBackupResourceType.ServiceUri); inheritedBackupMapping = await backupMappingStore.GetValueAsync(applicationNameUri, transaction); break; case FabricBackupResourceType.PartitionUri: inheritedBackupMapping = await backupMappingStore.GetValueAsync(serviceNameUri, transaction); if (inheritedBackupMapping == null) { inheritedBackupMapping = await backupMappingStore.GetValueAsync(applicationNameUri, transaction); } filteredPartitionList.Add(partitionID); break; } foreach (var partitionId in filteredPartitionList) { // there can be only one inherited backup policy for a single URI. BackupRestoreTrace.TraceSource.WriteInfo(TraceType, " Trying to start DisablePolicyTask for partitionId : {0}", partitionId); await DisablePolicyAsync(currentBackupPolicy, partitionId, inheritedBackupMapping, timeout, cancellationToken, transaction); BackupRestoreTrace.TraceSource.WriteInfo(TraceType, " Succesfully started DisablePolicyTask for partitionId : {0}", partitionId); } }
internal async Task InitialiseRetentionManager() { this.RetentionStore = await RetentionStore.CreateOrGetRetentionStore(StatefulService); this.CleanupStore = await CleanupStore.CreateOrGetCleanupStore(StatefulService); // Initialise RetentionSchedulerDict using RetentionStore and retention schedulers BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Intialising Retention Manager"); using (ITransaction transaction = this.StatefulService.StateManager.CreateTransaction()) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Recreating RetentionSchedulerDict."); List <Tuple <string, RetentionMetadata> > listOfTuple = await this.RetentionStore.GetTupleListAsyncUtils(transaction, this.tokenSource.Token); foreach (var tuple in listOfTuple) { if (!this.RetentionSchedulerDict.TryAdd(tuple.Item1, new RetentionScheduler(tuple.Item1, tuple.Item2.CurrentRetentionPolicy, timerCallback))) { BackupRestoreTrace.TraceSource.WriteError(TraceType, "Not able to add retention scheduler for backupPolicy : {0}", tuple.Item1); throw new InvalidOperationException(string.Format("{0}: Key already exists ", tuple.Item1)); } } // Start all the cleanUp Tasks again. BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Starting all the previous cleanup tasks."); List <Tuple <string, List <string> > > listOfTuple2 = await this.CleanupStore.GetTupleListAsyncUtils(transaction, this.tokenSource.Token); int counter = 0; foreach (var tuple in listOfTuple2) { var backupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.StatefulService); var backupPolicy = await backupPolicyStore.GetValueAsync(tuple.Item1, transaction); if (tuple.Item2 != null && tuple.Item2.Count > 0) { counter += tuple.Item2.Count; tuple.Item2.ForEach((partition => { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Starting cleanUp task for partition : {0} and backupPolicy : {1}", partition, backupPolicy.Name); Task task = CleanUpTaskUtil(partition, backupPolicy); })); } } BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Number of cleanup Tasks started : {0}", counter); } }
/// <summary> /// Gets called when a policy is updated /// </summary> internal async Task UpdatePolicyAsync(string backupPolicyName, TimeSpan timeout, CancellationToken cancellationToken, ITransaction transaction) { /** * Cases: * 1. UpdateRetention ----> Re-arm the timer. * 0. Add Retention. * a. Remove retention --> dispose the timer. * b. update the retention. * 2. UpdateStorage ----> * 3. Update Backup Schedule. --> no need to do anything/ * */ try { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, " In UpdatePolicyAsync of Retention Manager for Backup policy: {0}", backupPolicyName); var backupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.StatefulService); RetentionMetadata retentionMetadata = await this.RetentionStore.GetValueAsync(backupPolicyName, timeout, cancellationToken, transaction); BackupPolicy backupPolicy = await backupPolicyStore.GetValueAsync(backupPolicyName, timeout, cancellationToken, transaction); if (retentionMetadata == null) { if (backupPolicy.RetentionPolicy != null) { retentionMetadata = new RetentionMetadata(backupPolicy.RetentionPolicy); await this.RetentionStore.AddAsync(backupPolicyName, retentionMetadata, timeout, cancellationToken, transaction); RetentionScheduler retentionScheduler = new RetentionScheduler(backupPolicy.Name, backupPolicy.RetentionPolicy, timerCallback); // Here we have updated the policy to introduce retention. retentionScheduler.ArmTimer(retentionMetadata, true); if (!RetentionSchedulerDict.TryAdd(backupPolicyName, retentionScheduler)) { // If we are not able to add retention in RetentionSchedulerDict then, stop timer in retention scheduler retentionScheduler.Stop(); BackupRestoreTrace.TraceSource.WriteWarning(TraceType, "UpdatePolicyAsync, Not able to add retentionScheduler to dict for policy : {0} ", backupPolicyName); throw new InvalidOperationException(string.Format("{0}: Key already exists.", backupPolicyName)); } } } else if (backupPolicy.RetentionPolicy == null) { // need to remove the retentionScheduler from RetentionStore. Func <bool> condition = () => { if (retentionMetadata.LastRetentionCompletionTime > retentionMetadata.LastRetentionStartTime || retentionMetadata.LastRetentionStartTime == DateTime.MinValue) { return(true); } return(false); }; bool disposeComplete = await BackupRestoreUtility.TryPerformOperationWithWaitAsync( (policyName, token) => { return(DisposeRetentionScheduler(policyName, timeout, token, transaction)); }, condition, backupPolicyName, cancellationToken, minimumWaitTimeForRetryOperationInMs, maxRetryCountForDisposingRetention, minimumWaitTimeForRetryOperationInMs); if (!disposeComplete) { BackupRestoreTrace.TraceSource.WriteError(TraceType, "Dispose retention did not complete for {0}", backupPolicyName); throw new FabricBackupRestoreLocalRetryException(); } } else { if (retentionMetadata.UpdateRetentionPolicyMetadata(backupPolicy.RetentionPolicy)) { // Update the retention Scheduler store and arm the timer. RetentionScheduler retentionScheduler; if (!RetentionSchedulerDict.TryGetValue(backupPolicyName, out retentionScheduler)) { BackupRestoreTrace.TraceSource.WriteError(TraceType, "UpdateBackupPolicy: Not able to get retention scheduler for backupPolicy {0}", backupPolicyName); throw new KeyNotFoundException(); } retentionScheduler.RearmTimer(false, retentionMetadata); await this.RetentionStore.UpdateValueAsync(backupPolicyName, retentionMetadata, timeout, cancellationToken, transaction); } } } catch (Exception ex) { if (ex is OperationCanceledException) { BackupRestoreTrace.TraceSource.WriteWarning(TraceType, " DisposeRetentionScheduler ended with Timeout as the operation was cencelled: {0}", backupPolicyName); BackupRestoreTrace.TraceSource.WriteWarning(TraceType, " It could be because the retention was in progress and user tried to remove the retention policy during UpdatePolicy: {0}", backupPolicyName); } else { // Check for the exceptions of DisposeRetentionScheduler Timeout Retries. BackupRestoreTrace.TraceSource.WriteError(TraceType, " UpdateBackupPolicy resulted in the exception : {0}", backupPolicyName); } throw; } }
internal async Task <HashSet <string> > FindParititionsEnabledByPolicy(BackupPolicy backupPolicy) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, " Finding all the partitions enabled for the backupPolicy : {0}", backupPolicy.Name); HashSet <string> partitionsEnabledByPolicy = new HashSet <string>(); var backupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.StatefulService); var backupMappingStore = await BackupMappingStore.CreateOrGetBackupMappingStore(this.StatefulService); var backupEnabledSet = backupPolicy.BackupEnabledSet.ToList(); foreach (var backupedUri in backupEnabledSet) { string applicationName = null; string serviceName = null; string partitionId = null; FabricBackupResourceType fabricBackupResourceType = UtilityHelper.GetApplicationAndServicePartitionUri(backupedUri, out applicationName, out serviceName, out partitionId); switch (fabricBackupResourceType) { case FabricBackupResourceType.PartitionUri: partitionsEnabledByPolicy.Add(partitionId); break; default: var partitionIDList = await GetPartitionsForServiceOrApplication(backupedUri, fabricBackupResourceType, this.timeout, this.tokenSource.Token); foreach (var partitionID in partitionIDList) { partitionsEnabledByPolicy.Add(partitionID); this.tokenSource.Token.ThrowIfCancellationRequested(); } break; } } List <string> partitionListToRemove = new List <string>(); foreach (var partitionId in partitionsEnabledByPolicy) { this.tokenSource.Token.ThrowIfCancellationRequested(); string serviceNameUri = await FabricClientHelper.GetFabricServiceUriFromPartitionId(partitionId, timeout, tokenSource.Token); string applicationNameUri = await FabricClientHelper.GetFabricApplicationUriFromServiceUri(serviceNameUri, timeout, tokenSource.Token); string partitionUri = await UtilityHelper.GetFabricUriFromPartitionId(partitionId, this.timeout, this.tokenSource.Token); var backupMapping = (await backupMappingStore.GetValueAsync(partitionUri, timeout, this.tokenSource.Token) ?? await backupMappingStore.GetValueAsync(serviceNameUri, this.timeout, tokenSource.Token)) ?? await backupMappingStore.GetValueAsync(applicationNameUri, this.timeout, tokenSource.Token); if (backupMapping.BackupPolicyName != backupPolicy.Name) { partitionListToRemove.Add(partitionId); } } foreach (var partitionId in partitionListToRemove) { partitionsEnabledByPolicy.Remove(partitionId); } return(partitionsEnabledByPolicy); }
/// <summary> /// Gets invoked when the RetentionScheduler's timer's time is elapsed /// </summary> internal void timerCallback(string backupPolicyName) { RetentionScheduler retentionScheduler; if (!RetentionSchedulerDict.TryGetValue(backupPolicyName, out retentionScheduler)) { BackupRestoreTrace.TraceSource.WriteWarning(TraceType, "RetentionScheduler object is not found in retentionScheduler dict for policy: {0}", backupPolicyName); return; } bool toRearm = true; RetentionMetadata retentionMetadata = this.RetentionStore.GetValueAsync(backupPolicyName, this.timeout, this.tokenSource.Token).GetAwaiter().GetResult(); try { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, " TimerCallback running for backupPolicy : {0}", backupPolicyName); var backupPolicyStore = BackupPolicyStore.CreateOrGetBackupPolicyStore(this.StatefulService).GetAwaiter().GetResult(); BackupPolicy backupPolicy = backupPolicyStore.GetValueAsync(backupPolicyName, this.timeout, this.tokenSource.Token).GetAwaiter().GetResult(); if (backupPolicy == null) { /** * This is used to garbage collect the retention scheduler. It could happen while deleting\updating policy retention scheduler object was not * stopped properly. So, timer will call its callback again just to find that the backup policy does not exists. * In this case, we should stop the retentionScheduler. * **/ RetentionScheduler retentionSchedulerToDelete; if (RetentionSchedulerDict.TryRemove(backupPolicyName, out retentionSchedulerToDelete)) { retentionSchedulerToDelete.Stop(); } else { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "TimerCallback TryRemove retentionSchedulerDict failed of policy {0}. It could happen" + " when residual callback already scheduled on threadpool thread is getting invoked.", backupPolicyName); } toRearm = false; return; } HashSet <string> partitionsEnabledByPolicy = FindParititionsEnabledByPolicy(backupPolicy).GetAwaiter().GetResult(); retentionMetadata.UpdateLastRetentionStartTime(); this.RetentionStore.UpdateValueAsync(backupPolicyName, retentionMetadata, this.timeout, this.tokenSource.Token, null).GetAwaiter().GetResult(); var derivedRetentionPolicy = (BasicRetentionPolicy)retentionMetadata.CurrentRetentionPolicy; TimeSpan retentionDuration = derivedRetentionPolicy.RetentionDuration; int minimumNumberOfBackups = derivedRetentionPolicy.MinimumNumberOfBackups; foreach (var partitionId in partitionsEnabledByPolicy) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, " Deleting backups for partitionId : {0}", partitionId); List <string> partitionList = this.CleanupStore.GetValueAsync(backupPolicyName, this.timeout, this.tokenSource.Token).GetAwaiter().GetResult(); if (!(partitionList == null || partitionList.Count == 0) && partitionList.Contains(partitionId)) { // Cleanup is going on for this partition. continue; } DateTime endDateFilter = DateTime.UtcNow - retentionDuration; BackupStorage storage = backupPolicy.Storage; DeleteFilesForPartition(partitionId, endDateFilter, minimumNumberOfBackups, storage, backupPolicyName).GetAwaiter().GetResult(); this.tokenSource.Token.ThrowIfCancellationRequested(); } // --> Introduce some wait time here so that CompletionTime is never equal to StartTime. retentionMetadata.UpdateLastRetentionCompletionTime(); this.RetentionStore.UpdateValueAsync(backupPolicyName, retentionMetadata).GetAwaiter().GetResult(); retentionScheduler.ArmTimer(retentionMetadata); toRearm = false; } catch (Exception ex) { if (ex is OperationCanceledException) { // Since, timercallback was cancelled, therefore, there is no need to rearm the timer. BackupRestoreTrace.TraceSource.WriteWarning(TraceType, " TimerCallback for backupPolicy : {0} was cancelled ", backupPolicyName); toRearm = false; } else { BackupRestoreTrace.TraceSource.WriteWarning(TraceType, " TimerCallback for backupPolicy : {0} has thrown an exception : {1}", backupPolicyName, ex); } } finally { if (toRearm) { retentionScheduler.RearmTimer(true, retentionMetadata); } } }
public async Task <BackupPolicy> GetBackupSchedulingPolicyAsync(BackupPartitionInfo backupPartitionInfo, TimeSpan timeout, CancellationToken cancellationToken) { BackupPolicy backupPolicy; BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "{0} GetBackupPolicy invoked", backupPartitionInfo.PartitionId); var backupMappingStore = await BackupMappingStore.CreateOrGetBackupMappingStore(this.statefulService); var backupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.statefulService); var suspendStore = await SuspendStore.CreateOrGetSuspendStatusStore(this.statefulService); var serviceNameUri = await UtilityHelper.GetCustomServiceUri(backupPartitionInfo.ServiceName, timeout, cancellationToken); var backupMappingKey = UtilityHelper.GetBackupMappingKey(serviceNameUri, backupPartitionInfo.PartitionId.ToString()); var backupMappingModel = (await backupMappingStore.GetValueAsync(backupMappingKey) ?? await backupMappingStore.GetValueAsync(serviceNameUri)) ?? await backupMappingStore.GetValueAsync(UtilityHelper.GetApplicationNameFromService(serviceNameUri)); bool isPartitionSuspended = await suspendStore.GetValueAsync(backupMappingKey) != null; if (backupMappingModel == null || isPartitionSuspended) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "{0} Backup protection not enabled", backupPartitionInfo.PartitionId); throw new FabricPeriodicBackupNotEnabledException(); } var backupPolicyName = backupMappingModel.BackupPolicyName; var backupPolicyModel = await backupPolicyStore.GetValueAsync(backupPolicyName); switch (backupPolicyModel.BackupSchedule.BackupScheduleType) { case BackupScheduleType.FrequencyBased: backupPolicy = new FrequencyBasedBackupPolicy(); var frequencyBasedSchedulePolicy = (System.Fabric.BackupRestore.Common.Model.FrequencyBasedBackupSchedule)backupPolicyModel.BackupSchedule; backupPolicy.PolicyType = BackupPolicyType.FrequencyBased; var freqBackupPolicy = (FrequencyBasedBackupPolicy)backupPolicy; freqBackupPolicy.RunFrequency = (ushort)frequencyBasedSchedulePolicy.Interval; if (frequencyBasedSchedulePolicy.IntervalType == BackupScheduleInterval.Hours) { freqBackupPolicy.RunFrequencyType = BackupPolicyRunFrequency.Hours; } if (frequencyBasedSchedulePolicy.IntervalType == BackupScheduleInterval.Minutes) { freqBackupPolicy.RunFrequencyType = BackupPolicyRunFrequency.Minutes; } break; case BackupScheduleType.TimeBased: backupPolicy = new ScheduleBasedBackupPolicy(); var scheduleBasedSchedulePolicy = (System.Fabric.BackupRestore.Common.Model.TimeBasedBackupSchedule)backupPolicyModel.BackupSchedule; backupPolicy.PolicyType = BackupPolicyType.ScheduleBased; var schdBackupPolicy = (ScheduleBasedBackupPolicy)backupPolicy; if (scheduleBasedSchedulePolicy.ScheduleFrequencyType == BackupScheduleFrequency.Daily) { schdBackupPolicy.RunSchedule = BackupPolicyRunSchedule.Daily; } if (scheduleBasedSchedulePolicy.ScheduleFrequencyType == BackupScheduleFrequency.Weekly) { schdBackupPolicy.RunSchedule = BackupPolicyRunSchedule.Weekly; } schdBackupPolicy.RunDays = new List <DayOfWeek>(scheduleBasedSchedulePolicy.RunDays); schdBackupPolicy.RunTimes = new List <TimeSpan>(scheduleBasedSchedulePolicy.RunTimes); break; default: throw new FabricPeriodicBackupNotEnabledException(); } backupPolicy.MaxIncrementalBackups = Convert.ToByte(backupPolicyModel.MaxIncrementalBackup); backupPolicy.Name = backupPolicyModel.Name; backupPolicy.PolicyId = backupPolicyModel.UniqueId; switch (backupPolicyModel.Storage.BackupStorageType) { case BackupStorageType.FileShare: var fileShareStorage = (System.Fabric.BackupRestore.Common.Model.FileShareBackupStorageInfo)backupPolicyModel.Storage; backupPolicy.StoreInformation = new FileShareBackupStore { AccessType = String.IsNullOrEmpty(fileShareStorage.PrimaryUserName) ? FileShareAccessType.None : FileShareAccessType.DomainUser, FileSharePath = Path.Combine(fileShareStorage.Path, UtilityHelper.GetBaseDirectoryPathForPartition(serviceNameUri, backupPartitionInfo.PartitionId.ToString())), PrimaryUserName = fileShareStorage.PrimaryUserName, PrimaryPassword = fileShareStorage.PrimaryPassword, SecondaryUserName = fileShareStorage.SecondaryUserName, SecondaryPassword = fileShareStorage.SecondaryPassword, IsPasswordEncrypted = fileShareStorage.IsPasswordEncrypted, }; break; case BackupStorageType.AzureBlobStore: var azureStorage = (System.Fabric.BackupRestore.Common.Model.AzureBlobBackupStorageInfo)backupPolicyModel.Storage; backupPolicy.StoreInformation = new AzureBlobBackupStore { ConnectionString = azureStorage.ConnectionString, ContainerName = azureStorage.ContainerName, FolderPath = UtilityHelper.GetBaseDirectoryPathForPartition(serviceNameUri, backupPartitionInfo.PartitionId.ToString()), IsAccountKeyEncrypted = azureStorage.IsConnectionStringEncrypted, }; break; case BackupStorageType.DsmsAzureBlobStore: var dsmsAzureStorage = (System.Fabric.BackupRestore.Common.Model.DsmsAzureBlobBackupStorageInfo)backupPolicyModel.Storage; backupPolicy.StoreInformation = new DsmsAzureBlobBackupStore { StorageCredentialsSourceLocation = dsmsAzureStorage.StorageCredentialsSourceLocation, ContainerName = dsmsAzureStorage.ContainerName, FolderPath = UtilityHelper.GetBaseDirectoryPathForPartition(serviceNameUri, backupPartitionInfo.PartitionId.ToString()), }; break; } return(backupPolicy); }
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); }