internal override async Task <HttpResponseMessage> RunAsync(TimeSpan timeout, CancellationToken cancellationToken) { string applicationNameUri; string serviceNameUri; string partitionId; var fabricUri = await UtilityHelper.GetFabricUriFromRequstHeader(this._fabricRequestHeader, timeout, cancellationToken); FabricBackupResourceType fabricBackupResourceType = UtilityHelper.GetApplicationAndServicePartitionUri(fabricUri, out applicationNameUri, out serviceNameUri, out partitionId); var suspendStore = await SuspendStore.CreateOrGetSuspendStatusStore(this.StatefulService); var backupMappingList = await this.BackupMappingStore.GetAllProtectionForApplicationAndItsServiceAndPartition(applicationNameUri, timeout, cancellationToken); if (backupMappingList.Count == 0) { throw new FabricPeriodicBackupNotEnabledException(); } WorkItem workItem = null; switch (fabricBackupResourceType) { case FabricBackupResourceType.ApplicationUri: workItem = new ResolveToPartitionWorkItem(FabricBackupResourceType.ApplicationUri, applicationNameUri, new WorkItemInfo { WorkItemType = WorkItemPropogationType.SuspendPartition }); break; case FabricBackupResourceType.ServiceUri: workItem = new ResolveToPartitionWorkItem(FabricBackupResourceType.ServiceUri, serviceNameUri, new WorkItemInfo { WorkItemType = WorkItemPropogationType.SuspendPartition }); break; case FabricBackupResourceType.PartitionUri: workItem = new SendToServiceNodeWorkItem(serviceNameUri, partitionId, new WorkItemInfo { WorkItemType = WorkItemPropogationType.SuspendPartition }); break; } if (fabricBackupResourceType == FabricBackupResourceType.Error || workItem == null) { throw new ArgumentException("Invalid argument"); } using (var transaction = this.StatefulService.StateManager.CreateTransaction()) { await suspendStore.AddOrUpdateAsync(fabricUri, fabricUri, (fabricUriKey, fabricUriValue) => fabricUriValue, timeout, cancellationToken, transaction); await this.WorkItemQueue.AddWorkItem(workItem, timeout, cancellationToken, transaction); await transaction.CommitAsync(); } return(new HttpResponseMessage(HttpStatusCode.Accepted)); }
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(); } } }); }
internal override async Task <HttpResponseMessage> RunAsync(TimeSpan timeout, CancellationToken cancellationToken) { WorkItem workItem = null; string applicationNameUri = null; string serviceNameUri = null; string partitionId = null; this.ThrowInvalidArgumentIfNull(this.backupMapping); var appOrServiceUri = await UtilityHelper.GetFabricUriFromRequstHeader(this.fabricRequestHeader, timeout, cancellationToken); BackupMappingModel backupMappingModel = BackupMappingModel.FromBackupMappingView(this.backupMapping, appOrServiceUri); FabricBackupResourceType fabricResourceType = UtilityHelper.GetApplicationAndServicePartitionUri(backupMappingModel.ApplicationOrServiceUri, out applicationNameUri, out serviceNameUri, out partitionId); bool isInputValid = false; string key = backupMappingModel.ApplicationOrServiceUri; BackupMappingModel existingBackupMapping = await this.BackupMappingStore.GetValueAsync(key, timeout, cancellationToken); BackupPolicyModel backupPolicy = await this.BackupPolicyStore.GetValueAsync(backupMappingModel.BackupPolicyName, timeout, cancellationToken); if (backupPolicy == null) { throw new FabricException(StringResources.BackupPolicyDoesNotExist, FabricErrorCode.BackupPolicyDoesNotExist); } WorkItemPropogationType workItemPropogationType = existingBackupMapping == null? WorkItemPropogationType.Enable : WorkItemPropogationType.UpdateProtection; WorkItemInfo workItemInfo = new WorkItemInfo { WorkItemType = workItemPropogationType, ProctectionGuid = backupMappingModel.ProtectionId, BackupPolicyUpdateGuid = backupPolicy.UniqueId }; switch (fabricResourceType) { case FabricBackupResourceType.ApplicationUri: isInputValid = await FabricClientHelper.ValidateApplicationUri(applicationNameUri, timeout, cancellationToken); workItem = new ResolveToPartitionWorkItem(fabricResourceType, backupMappingModel.ApplicationOrServiceUri, workItemInfo); break; case FabricBackupResourceType.ServiceUri: isInputValid = await FabricClientHelper.ValidateServiceUri(serviceNameUri, timeout, cancellationToken); workItem = new ResolveToPartitionWorkItem(fabricResourceType, backupMappingModel.ApplicationOrServiceUri, workItemInfo); break; case FabricBackupResourceType.PartitionUri: isInputValid = await FabricClientHelper.ValidateServiceUri(serviceNameUri, timeout, cancellationToken); if (isInputValid) { isInputValid = await FabricClientHelper.ValidatePartition(serviceNameUri, partitionId, timeout, cancellationToken); workItem = new SendToServiceNodeWorkItem(serviceNameUri, partitionId, workItemInfo); } break; case FabricBackupResourceType.Error: throw new ArgumentException("Invalid argument"); } if (!isInputValid) { throw new ArgumentException("Invalid Arguments for Application / Service / Partitions Details."); } using (var transaction = this.StatefulService.StateManager.CreateTransaction()) { await this.BackupMappingStore.AddOrUpdateAsync(key, backupMappingModel, (key1, BackupMappingModel1) => backupMappingModel, timeout, cancellationToken); await this.WorkItemQueue.AddWorkItem(workItem, timeout, cancellationToken, transaction); BackupPolicyModel existingBackupPolicy = await this.BackupPolicyStore.GetValueWithUpdateLockModeAsync(backupMappingModel.BackupPolicyName, timeout, cancellationToken, transaction); if (existingBackupMapping != null) { BackupPolicyModel previousBackupPolicy = await this.BackupPolicyStore.GetValueWithUpdateLockModeAsync(existingBackupMapping.BackupPolicyName, timeout, cancellationToken, transaction); await this.BackupPolicyStore.RemoveProtectionEntity(previousBackupPolicy, key, timeout, cancellationToken, transaction); } await this.BackupPolicyStore.AddProtectionEntity(existingBackupPolicy, key, timeout, cancellationToken, transaction); cancellationToken.ThrowIfCancellationRequested(); await transaction.CommitAsync(); } return(new HttpResponseMessage(HttpStatusCode.Accepted)); }
internal override async Task <HttpResponseMessage> RunAsync(TimeSpan timeout, CancellationToken cancellationToken) { string applicationNameUri; string serviceNameUri; string partitionId; var fabricUri = await UtilityHelper.GetFabricUriFromRequstHeader(this.fabricRequestHeader, timeout, cancellationToken); WorkItem workItem = null; FabricBackupResourceType fabricBackupResourceType = UtilityHelper.GetApplicationAndServicePartitionUri(fabricUri, out applicationNameUri, out serviceNameUri, out partitionId); bool isApplicationOrServiceExisting; switch (fabricBackupResourceType) { case FabricBackupResourceType.ApplicationUri: isApplicationOrServiceExisting = await this.IsApplicationOrServiceExisting(fabricBackupResourceType, applicationNameUri, null, timeout, cancellationToken); if (isApplicationOrServiceExisting) { workItem = new ResolveToPartitionWorkItem(FabricBackupResourceType.ApplicationUri, applicationNameUri, new WorkItemInfo { WorkItemType = WorkItemPropogationType.Disable, }); } break; case FabricBackupResourceType.ServiceUri: isApplicationOrServiceExisting = await this.IsApplicationOrServiceExisting(fabricBackupResourceType, serviceNameUri, null, timeout, cancellationToken); if (isApplicationOrServiceExisting) { workItem = new ResolveToPartitionWorkItem(FabricBackupResourceType.ServiceUri, serviceNameUri, new WorkItemInfo { WorkItemType = WorkItemPropogationType.Disable, }); } break; case FabricBackupResourceType.PartitionUri: isApplicationOrServiceExisting = await this.IsApplicationOrServiceExisting(fabricBackupResourceType, serviceNameUri, partitionId, timeout, cancellationToken); if (isApplicationOrServiceExisting) { serviceNameUri = await FabricClientHelper.GetFabricServiceUriFromPartitionId(partitionId, timeout, cancellationToken); workItem = new SendToServiceNodeWorkItem(serviceNameUri, partitionId, new WorkItemInfo { WorkItemType = WorkItemPropogationType.Disable, }); } break; case FabricBackupResourceType.Error: throw new ArgumentException(StringResources.InvalidArguments); } if (workItem == null) { using (var transaction = this.StatefulService.StateManager.CreateTransaction()) { var backupMapping = await this.BackupMappingStore.GetValueWithUpdateLockModeAsync(fabricUri, timeout, cancellationToken, transaction); if (backupMapping == null) { throw new FabricPeriodicBackupNotEnabledException(); } var assignedBackupPolicy = await this.BackupPolicyStore.GetValueWithUpdateLockModeAsync(backupMapping.BackupPolicyName, timeout, cancellationToken, transaction); await this.BackupMappingStore.DeleteValueAsync(fabricUri, timeout, cancellationToken, transaction); await this.BackupPolicyStore.RemoveProtectionEntity(assignedBackupPolicy, fabricUri, timeout, cancellationToken, transaction); await transaction.CommitAsync(); } } else { RetentionManager retentionManager = await RetentionManager.CreateOrGetRetentionManager(this.StatefulService); using (var transaction = this.StatefulService.StateManager.CreateTransaction()) { var backupMapping = await this.BackupMappingStore.GetValueWithUpdateLockModeAsync(fabricUri, timeout, cancellationToken, transaction); if (backupMapping == null) { throw new FabricPeriodicBackupNotEnabledException(); } var assignedBackupPolicy = await this.BackupPolicyStore.GetValueWithUpdateLockModeAsync(backupMapping.BackupPolicyName, timeout, cancellationToken, transaction); await this.BackupMappingStore.DeleteValueAsync(fabricUri, timeout, cancellationToken, transaction); await this.BackupPolicyStore.RemoveProtectionEntity(assignedBackupPolicy, fabricUri, timeout, cancellationToken, transaction); await this.WorkItemQueue.AddWorkItem(workItem, timeout, cancellationToken, transaction); if (cleanBackups) { await retentionManager.DisablePolicyAsync(fabricUri, backupMapping, timeout, cancellationToken, transaction); } await transaction.CommitAsync(); } } return(new HttpResponseMessage(HttpStatusCode.Accepted)); }