Example #1
0
        private async Task ValidateInput()
        {
            if (!this.ModelState.IsValid)
            {
                this.LogErrorInModels();
                var badRequestMessage = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                                                                         this.ModelState);
                var badRequestMessageDetails = await badRequestMessage.Content.ReadAsStringAsync();

                var fabricBackupRestoreInputValidationError = new FabricErrorError(new FabricError
                {
                    Message = badRequestMessageDetails.Replace(@"""", ""),
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG
                });
                throw new HttpResponseException(fabricBackupRestoreInputValidationError.ToHttpResponseMessage());
            }
        }
        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,
                });
            }
        }
Example #3
0
        internal async Task <TResult> RunAsync <TResult>(BaseOperation <TResult> operationBase, int timeoutInSeconds)
        {
            var cancellationTokenSource = new CancellationTokenSource();

            if (timeoutInSeconds <= 0)
            {
                throw new ArgumentException(StringResources.InvalidTimeout);
            }

            var timeout = new TimeSpan(0, 0, timeoutInSeconds);

            cancellationTokenSource.CancelAfter(timeout);
            BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Controller {0} Operation requested : {1}", this.GetType(), operationBase);
            await this.ValidateInput();

            do
            {
                try
                {
                    this._retryCount++;
                    return(await operationBase.RunAsyncWrappper(timeout, cancellationTokenSource.Token));
                }
                catch (HttpResponseException)
                {
                    throw;
                }
                catch (Exception exception)
                {
                    this.LogException(TraceType, exception);
                    var fabricException = exception as FabricException;
                    if (fabricException != null)
                    {
                        var fabricError = new FabricError(fabricException);
                        var fabricBackupRestoreError = new FabricErrorError(fabricError);
                        throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                    }
                    else if (exception is ArgumentException)
                    {
                        FabricErrorError fabricBackupRestoreError = new FabricErrorError(new FabricError()
                        {
                            Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                            Message = exception.Message
                        });
                        throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                    }
                    else if (exception is OperationCanceledException || exception is TimeoutException)
                    {
                        FabricErrorError fabricBackupRestoreError = new FabricErrorError(new FabricError()
                        {
                            Code    = NativeTypes.FABRIC_ERROR_CODE.FABRIC_E_TIMEOUT,
                            Message = StringResources.RequestTimeout
                        });
                        throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                    }
                    else if (exception is FabricBackupRestoreLocalRetryException)  //TODO Remove this and change to correct message
                    {
                        if (this._retryCount >= MaxRetryCount)
                        {
                            throw;
                        }
                    }
                    else
                    {
                        var stringBuilder = new StringBuilder();
                        if (exception is AggregateException)
                        {
                            var aggregateException = (AggregateException)exception;
                            foreach (var innerException in aggregateException.InnerExceptions)
                            {
                                stringBuilder.AppendFormat("{0} ,", innerException.Message).AppendLine();
                            }
                        }
                        else
                        {
                            stringBuilder.AppendFormat("{0}", exception.Message);
                        }
                        FabricErrorError fabricBackupRestoreError = new FabricErrorError(new FabricError()
                        {
                            Message = stringBuilder.ToString(),
                            Code    = NativeTypes.FABRIC_ERROR_CODE.E_UNEXPECTED
                        });
                        throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                    }
                }
            } while (this._retryCount <= MaxRetryCount);
            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }
Example #4
0
        internal async Task <TResult> RunAsync <TResult>(BaseOperation <TResult> operationBase, int timeoutInSeconds = (2 * 60))
        {
            var cancellationTokenSource = new CancellationTokenSource();

            if (timeoutInSeconds <= 0)
            {
                throw new ArgumentException("Invalid Timeout");
            }

            var timeout = new TimeSpan(0, 0, timeoutInSeconds);

            cancellationTokenSource.CancelAfter(timeout);

            await this.ValidateInputAsync();

            try
            {
                var startTime = DateTimeOffset.UtcNow;

                var results = await operationBase.RunAsyncWrappper(timeout, cancellationTokenSource.Token).ConfigureAwait(false);

                return(results);
            }
            catch (Exception exception)
            {
                FabricEvents.Events.EventStoreFailed(operationBase.GetSupportedEntityType().ToString(), ExtractDetails(exception));

                if (exception is ConnectionParsingException)
                {
                    // This indicates to the caller that the API's are not available as the connection information is not configured.
                    throw new HttpResponseException(HttpStatusCode.ServiceUnavailable);
                }

                if (exception is HttpResponseException)
                {
                    throw;
                }

                var fabricException = exception as FabricException;
                if (fabricException != null)
                {
                    var fabricError = new FabricError(fabricException);
                    var fabricBackupRestoreError = new FabricErrorError(fabricError);
                    throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                }
                else if (exception is ArgumentException)
                {
                    FabricErrorError fabricEventStoreSvcErrorMessage = new FabricErrorError(
                        new FabricError
                    {
                        Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                        Message = exception.Message
                    });
                    throw new HttpResponseException(fabricEventStoreSvcErrorMessage.ToHttpResponseMessage());
                }
                else if (exception is OperationCanceledException || exception is TimeoutException)
                {
                    FabricErrorError fabricEventStoreSvcErrorMessage = new FabricErrorError(
                        new FabricError
                    {
                        Code    = NativeTypes.FABRIC_ERROR_CODE.FABRIC_E_TIMEOUT,
                        Message = "Timeout"
                    });
                    throw new HttpResponseException(fabricEventStoreSvcErrorMessage.ToHttpResponseMessage());
                }
                else
                {
                    var stringBuilder = new StringBuilder();
                    if (exception is AggregateException)
                    {
                        var aggregateException = (AggregateException)exception;
                        foreach (var innerException in aggregateException.InnerExceptions)
                        {
                            stringBuilder.AppendFormat("{0} ,", innerException.Message).AppendLine();
                        }
                    }
                    else
                    {
                        stringBuilder.AppendFormat("{0}", exception.Message);
                    }
                    FabricErrorError fabricEventStoreSvcErrorMessage = new FabricErrorError(
                        new FabricError
                    {
                        Message = stringBuilder.ToString(),
                        Code    = NativeTypes.FABRIC_ERROR_CODE.E_UNEXPECTED
                    });
                    throw new HttpResponseException(fabricEventStoreSvcErrorMessage.ToHttpResponseMessage());
                }
            }

            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }