internal override async Task <RestorePointEnumerationResult> RunAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            RestorePointEnumerationResult restorePoints = new RestorePointEnumerationResult();

            this.ThrowInvalidArgumentIfNull(this.backupStorage);
            BackupStorageModel backupStorageModel = BackupStorageModel.FromBackupStorageView(this.backupStorage);

            await this.PopulateApplicationServiceAndPartitionWithBackupStorage(timeout, cancellationToken);

            try
            {
                List <RestorePoint> fetchedRestorePoints = await
                                                           backupStorageModel.GetBackupEnumerationsTask(this.ApplicationName, this.ServiceName,
                                                                                                        this.PartitionId, this.startDateTime, this.endDateTime, cancellationToken);

                if (fetchedRestorePoints != null && fetchedRestorePoints.Count > 0)
                {
                    restorePoints.RestorePoints = fetchedRestorePoints;
                }
            }
            catch (Exception exception)
            {
                List <RestorePointEnumerationFailureInfo> restorePointEnumerationFailureInfo =
                    new List <RestorePointEnumerationFailureInfo>();
                AggregateException aggregateException = exception as AggregateException;
                if (aggregateException != null)
                {
                    foreach (var innerException in aggregateException.InnerExceptions)
                    {
                        restorePointEnumerationFailureInfo.Add(new RestorePointEnumerationFailureInfo
                                                                   ()
                        {
                            Error =
                                new FabricError()
                            {
                                Code    = (NativeTypes.FABRIC_ERROR_CODE)innerException.HResult,
                                Message = innerException.Message
                            }
                        });
                    }
                }
                else
                {
                    restorePointEnumerationFailureInfo.Add(new RestorePointEnumerationFailureInfo
                                                               ()
                    {
                        Error =
                            new FabricError()
                        {
                            Code    = (NativeTypes.FABRIC_ERROR_CODE)exception.HResult,
                            Message = exception.Message
                        }
                    });
                }
            }
            return(restorePoints);
        }
Пример #2
0
        internal override async Task <PagedBackupInfoList> RunAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            BRSContinuationToken continuationTokenForNextStage = new BRSContinuationToken();

            if (continuationToken != null)
            {
                continuationTokenForNextStage.IncomingContinuationToken = continuationToken;
            }
            List <RestorePoint> restorePoints = new List <RestorePoint>();

            this.ThrowInvalidArgumentIfNull(this.backupByStorageQueryDescription.Storage);
            BackupStorageModel backupStorageModel = BackupStorageModel.FromBackupStorageView(this.backupByStorageQueryDescription.Storage);

            this.PopulateApplicationServiceAndPartitionWithBackupEntity(this.backupByStorageQueryDescription.BackupEntity,
                                                                        timeout, cancellationToken);
            try
            {
                List <RestorePoint> fetchedRestorePoints = await
                                                           backupStorageModel.GetBackupEnumerationsTask(
                    this.ApplicationName,
                    this.ServiceName,
                    this.PartitionId,
                    this.backupByStorageQueryDescription.StartDateTimeFilter,
                    this.backupByStorageQueryDescription.EndDateTimeFilter,
                    this.backupByStorageQueryDescription.Latest,
                    cancellationToken, continuationTokenForNextStage, maxResults);

                if (fetchedRestorePoints != null && fetchedRestorePoints.Count > 0)
                {
                    restorePoints = fetchedRestorePoints;
                }
            }
            catch (Exception exception)
            {
                List <RestorePointEnumerationFailureInfo> restorePointEnumerationFailureInfo =
                    new List <RestorePointEnumerationFailureInfo>();
                AggregateException aggregateException = exception as AggregateException;
                if (aggregateException != null)
                {
                    foreach (var innerException in aggregateException.InnerExceptions)
                    {
                        restorePoints.Add(new RestorePoint
                                              ()
                        {
                            FailureError =
                                new FabricError()
                            {
                                Code    = (NativeTypes.FABRIC_ERROR_CODE)innerException.HResult,
                                Message = innerException.Message
                            }
                        });
                    }
                }
                else
                {
                    restorePoints.Add(new RestorePoint
                                          ()
                    {
                        FailureError =
                            new FabricError()
                        {
                            Code    = (NativeTypes.FABRIC_ERROR_CODE)exception.HResult,
                            Message = exception.Message
                        }
                    });
                }
            }

            return(new PagedBackupInfoList()
            {
                Items = restorePoints,
                ContinuationToken = continuationTokenForNextStage.OutgoingContinuationToken
            });
        }
        internal override async Task <PagedBackupInfoList> RunAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            // Reading the value of continuationToken and maxResults.
            string continuationTokenLocal = this.continuationToken;
            int    maxResultsLocal        = this.maxResults;

            // Finding all the continuationTokens.
            string storageIdToContinue = null;
            BRSContinuationToken continuationTokenForNextStage = new BRSContinuationToken();
            string incomingContinuationTokenForNextStage       = null;

            if (!String.IsNullOrEmpty(continuationTokenLocal))
            {
                // Splitting only in 2 as first one will be storage id and other one will be continuationToken for next stage.
                List <string> continuationTokenList = continuationTokenLocal.Split(new char[] { ContinuationTokenSeparatorChar }, 2).ToList();
                storageIdToContinue = continuationTokenList[0];
                if (continuationTokenList.Count > 1)
                {
                    incomingContinuationTokenForNextStage = continuationTokenList[1];
                }
            }

            List <RestorePoint>       restorePoints        = new List <RestorePoint>();
            List <BackupMappingModel> listOfBackupMappings = await this.GetBackupMappings(timeout, cancellationToken);

            IEnumerable <string> backupPolicyMappingList =
                listOfBackupMappings.Select <BackupMappingModel, string>((backupMapping) =>
            {
                return(backupMapping.BackupPolicyName);
            });
            HashSet <string>             backupPolicyHashSetName = new HashSet <string>();
            HashSet <BackupStorageModel> backupStorages          = new HashSet <BackupStorageModel>();

            foreach (var backPolicyName in backupPolicyMappingList)
            {
                if (!backupPolicyHashSetName.Contains(backPolicyName))
                {
                    backupPolicyHashSetName.Add(backPolicyName);
                    BackupStorageModel backupStorage = (await this.BackupPolicyStore.GetValueAsync(backPolicyName, timeout, cancellationToken)).Storage;

                    if (!backupStorages.Contains(backupStorage))
                    {
                        backupStorages.Add(backupStorage);
                    }
                }
            }

            bool   isSuccess = true;
            string continuationTokenFinal = null;
            List <BackupStorageModel> backupStorageList = backupStorages.ToList();

            if (maxResultsLocal != 0)
            {
                // Ordering only when maxResults is not equal to 0.
                backupStorageList = backupStorageList.OrderBy(backupStorage => backupStorage.StorageId.ToString()).ToList();
                int  maxResultsLeft = maxResultsLocal;
                bool breakTheLoop   = false;


                // TO DO:
                // It is used for the case when maxResults is equal to number of elements in that storage.
                // In that condition, we will check for the next storage, if there is any more storages left to scan, we will send the storage id of the last storage scanned.
                // Here, we dont scan the next storage. There is a possibility that the next storage is empty.
                bool sendTheSameStorageAsContinuationToken = false;
                bool otherStorageFound = false;
                foreach (var backupStorage in backupStorageList)
                {
                    if (backupStorage.StorageId.ToString().CompareTo(storageIdToContinue) >= 0)
                    {
                        if (sendTheSameStorageAsContinuationToken)
                        {
                            // It means that we have found the next storage and we should break.
                            otherStorageFound = true;
                            break;
                        }
                        continuationTokenFinal = backupStorage.StorageId.ToString();
                        if (storageIdToContinue == backupStorage.StorageId.ToString())
                        {
                            if (String.IsNullOrEmpty(incomingContinuationTokenForNextStage))
                            {
                                // if we are here, then, we are in the condition of sendTheSameStorageAsContinuationToken = true in previouse query.
                                continue;
                            }
                            // continuationTokenForNextStage for this storage should be the incomingContinuationTokenForNextStage
                            continuationTokenForNextStage.IncomingContinuationToken = incomingContinuationTokenForNextStage;
                        }
                        else
                        {
                            // continuationTokenForNextStage for other storages should have IncomingContinuationToken to be null.
                            continuationTokenForNextStage.IncomingContinuationToken = null;
                        }
                        try
                        {
                            List <RestorePoint> newRestorePoints = new List <RestorePoint>();
                            newRestorePoints = await backupStorage.StartGetBackupEnumerationsTask(
                                this.ApplicationName,
                                this.ServiceName,
                                this.PartitionId,
                                this.isLatestRequested,
                                cancellationToken, continuationTokenForNextStage,
                                this.startDateTime,
                                this.endDateTime, maxResultsLeft);

                            restorePoints.AddRange(newRestorePoints);
                            maxResultsLeft = maxResultsLeft - newRestorePoints.Count;
                            if (maxResultsLeft == 0)
                            {
                                if (continuationTokenForNextStage.OutgoingContinuationToken == null)
                                {
                                    sendTheSameStorageAsContinuationToken = true;
                                }
                                else
                                {
                                    breakTheLoop = true;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            isSuccess        = false;
                            restorePoints[0] = new RestorePoint()
                            {
                                FailureError = new FabricError()
                                {
                                    Code    = (NativeTypes.FABRIC_ERROR_CODE)ex.HResult,
                                    Message = ex.Message
                                }
                            };
                        }
                    }
                    if (breakTheLoop || isSuccess == false)
                    {
                        break;
                    }
                }

                if (!isSuccess && restorePoints.Count > 0)
                {
                    // Here, always the restorePoints's first element will be having error details. Look DoThisOnTaskFaulted method.
                    FabricErrorError fabricErrorError = new FabricErrorError(restorePoints[0].FailureError);
                    throw new HttpResponseException(fabricErrorError.ToHttpResponseMessage());
                }

                continuationTokenLocal = null;
                if (continuationTokenForNextStage.OutgoingContinuationToken == null)
                {
                    if (sendTheSameStorageAsContinuationToken && otherStorageFound)
                    {
                        // if there is some next store available to scan, then, we have to send the current storageID as continuationToken
                        continuationTokenLocal = continuationTokenFinal;
                    }
                }
                else
                {
                    continuationTokenLocal = continuationTokenFinal + ContinuationTokenSeparatorChar + continuationTokenForNextStage.OutgoingContinuationToken;
                }

                return(new PagedBackupInfoList()
                {
                    Items = restorePoints,
                    ContinuationToken = continuationTokenLocal
                });
            }
            else
            {
                // we don't have to sort the storage list here as we need to return the complete list.
                List <Task> backupStorageTaskList = new List <Task>();
                foreach (var backupStorage in backupStorageList)
                {
                    Task backupStorageTask;
                    if (backupStorage.StorageId.ToString().CompareTo(storageIdToContinue) >= 0)
                    {
                        continuationTokenFinal = backupStorage.StorageId.ToString();
                        if (storageIdToContinue == backupStorage.StorageId.ToString())
                        {
                            if (String.IsNullOrEmpty(incomingContinuationTokenForNextStage))
                            {
                                continue;
                            }

                            // It is a possibility that continuationToken is not null for this stage then, we need to send the appropriate continuationToken.
                            continuationTokenForNextStage.IncomingContinuationToken = incomingContinuationTokenForNextStage;
                            backupStorageTask = backupStorage.StartGetBackupEnumerationsTask(
                                this.ApplicationName,
                                this.ServiceName,
                                this.PartitionId,
                                this.isLatestRequested,
                                cancellationToken, continuationTokenForNextStage,
                                this.startDateTime,
                                this.endDateTime).ContinueWith((task) =>
                            {
                                if ((!task.IsCanceled) && (!task.IsFaulted) && (task.IsCompleted))
                                {
                                    DoThisOnTaskSuccess(task, restorePoints, ref isSuccess);
                                }
                                else if (task.IsFaulted)
                                {
                                    DoThisOnTaskFaulted(task, restorePoints, ref isSuccess);
                                }
                            });
                        }
                        else
                        {
                            // Usual case for other storages.
                            backupStorageTask = backupStorage.StartGetBackupEnumerationsTask(
                                this.ApplicationName,
                                this.ServiceName,
                                this.PartitionId,
                                this.isLatestRequested,
                                cancellationToken, null,
                                this.startDateTime,
                                this.endDateTime).ContinueWith((task) =>
                            {
                                if ((!task.IsCanceled) && (!task.IsFaulted) && (task.IsCompleted))
                                {
                                    DoThisOnTaskSuccess(task, restorePoints, ref isSuccess);
                                }
                                else if (task.IsFaulted)
                                {
                                    DoThisOnTaskFaulted(task, restorePoints, ref isSuccess);
                                }
                            });
                        }
                        backupStorageTaskList.Add(backupStorageTask);
                    }
                }
                Task.WaitAll(backupStorageTaskList.ToArray(), cancellationToken);
                if (!isSuccess && restorePoints.Count > 0)
                {
                    FabricErrorError fabricErrorError = new FabricErrorError(restorePoints[0].FailureError);
                    throw new HttpResponseException(fabricErrorError.ToHttpResponseMessage());
                }

                return(new PagedBackupInfoList()
                {
                    Items = restorePoints,
                });
            }
        }