/// <summary>
        /// Run method
        /// 1: Reads messages from the table storage in ascending order.
        /// 2: Executes the delete or create operation on the destination blob.
        /// </summary>
        /// <returns></returns>
        public async Task Run(RestoreReqResponse reqResponse)
        {
            _logger.LogDebug("Begin: RestoreBackupWorker.Run");

            //Since there can be many records around 84K for a day, let's read the records day by day and perform the restore operation

            List <Tuple <int, int, DateTime> > dates = GetDatesForDateRange(reqResponse.StDate, reqResponse.EnDate);

            _logger.LogInformation($"Number of dates determined.---{dates.Count()}");

            int totalSuccessCount = 0;

            int totalFailureCount = 0;

            foreach (Tuple <int, int, DateTime> dateData in dates)
            {
                _logger.LogInformation($"Starting restore for Year {dateData.Item1} Week {dateData.Item2} and Date {dateData.Item3.ToString("MM/dd/yyyy")}");

                var blobEvents = await _logRepository.GetBLOBEvents(dateData.Item1, dateData.Item2, dateData.Item3, dateData.Item3.AddDays(1));

                _logger.LogInformation($"Found {blobEvents.Count} for {dateData.Item1} and Date {dateData.Item3.ToString("MM/dd/yyyy")}");

                if (blobEvents != null && blobEvents.Count > 0)
                {
                    foreach (EventData eventData in blobEvents)
                    {
                        try
                        {
                            if (eventData.ReceivedEventData is BlobEvent <CreatedEventData> )
                            {
                                BlobEvent <CreatedEventData> createdBlob = (BlobEvent <CreatedEventData>)eventData.ReceivedEventData;

                                if (eventData.DestinationBlobInfo != null)
                                {
                                    if ((!String.IsNullOrEmpty(reqResponse.ContainerName)) && (!String.Equals(eventData.DestinationBlobInfo.OrgContainerName, reqResponse.ContainerName)))
                                    {
                                        continue;
                                    }

                                    if ((reqResponse.BlobNames != null) && (!reqResponse.BlobNames.Contains(eventData.DestinationBlobInfo.OrgBlobName)))
                                    {
                                        continue;
                                    }

                                    _logger.LogInformation($"Going to perform copy as it is a created event {createdBlob.data.url}");
                                    await _blobRepository.CopyBlobFromBackupToRestore(eventData.DestinationBlobInfo);
                                }
                                else
                                {
                                    _logger.LogInformation($"Copy of the blob will be ignored as at the time of backup the blob was not present at source. One of the cause can be , a delete has been performed already on this blob. {createdBlob.data.url}");
                                    continue;
                                }
                            }
                            else if (eventData.ReceivedEventData is BlobEvent <DeletedEventData> )
                            {
                                BlobEvent <DeletedEventData> deletedBlob = (BlobEvent <DeletedEventData>)eventData.ReceivedEventData;

                                if (reqResponse.SkipDeletes.ToUpper(new CultureInfo("en-US", false)).Equals(Constants.Constants.RESTORE_SKIP_DELETES_YES))
                                {
                                    continue;
                                }

                                if ((!String.IsNullOrEmpty(reqResponse.ContainerName)) && (!deletedBlob.data.url.Contains(reqResponse.ContainerName)))
                                {
                                    continue;
                                }

                                if ((reqResponse.BlobNames != null) && (!reqResponse.BlobNames.Exists(x => deletedBlob.data.url.Contains(x))))
                                {
                                    continue;
                                }

                                _logger.LogInformation($"Going to perform delete as it is a deleted event {deletedBlob.data.url}");
                                await _blobRepository.DeleteBlobFromRestore(eventData.ReceivedEventData);
                            }
                            else
                            {
                                _logger.LogInformation($"Currently only Created and Deleted events are supported. Event Data: {eventData.ReceivedEventDataJSON}");
                                continue;
                            }

                            totalSuccessCount++;
                        }
                        catch (Exception ex)
                        {
                            totalFailureCount++;
                            _logger.LogError($"Exception while restoring event {eventData.ReceivedEventDataJSON}. Exception {ex.ToString()}");
                        }
                        if (reqResponse.ReqType.Equals(Constants.Constants.RESTORE_REQUEST_TYPE_ASYNC) && (totalSuccessCount % _updateFrequencyCount == 0))
                        {
                            reqResponse.TotalSuccessCount = totalSuccessCount;
                            reqResponse.TotalFailureCount = totalFailureCount;
                            await _restoreTblRepository.UpdateRestoreRequest(reqResponse);
                        }
                        ;
                    }
                    ;
                    // Update the processed record count for async restore request
                }
            }
            ;  // End of outer For loop

            _logger.LogInformation($"Restore Success records count: {totalSuccessCount}. Restore Failure records count: {totalFailureCount}.");
            reqResponse.TotalSuccessCount = totalSuccessCount;
            reqResponse.TotalFailureCount = totalFailureCount;

            _logger.LogDebug("End: RestoreBackupWorker.Run");
        }
Exemple #2
0
        public async Task Run(
            [TimerTrigger("%RestoreTriggerSchedule%")] TimerInfo callTimer,
            Microsoft.Extensions.Logging.ILogger log)
        {
            if (callTimer.IsPastDue)
            {
                log.LogInformation("PerformBackup: Timer is running late!");
            }

            log.LogInformation($"PerformRestoreAsync: Invoked at: {DateTime.Now}");
            Stopwatch          stopWatch   = new Stopwatch();
            RestoreReqResponse reqRespData = null;

            try
            {
                // Fetch an asynchronous restore request
                reqRespData = await _restoreTable.GetRestoreRequest();

                if (reqRespData != null)
                {
                    stopWatch.Start();

                    // Update the status of the restore request to in-progress
                    reqRespData.Status    = Constants.RESTORE_STATUS_INPROCESS;
                    reqRespData.StartTime = DateTime.Now.ToString();
                    await _restoreTable.UpdateRestoreRequest(reqRespData);

                    // Execute the restore process
                    DateTime startDate = DateTime.MinValue;
                    DateTime endDate   = DateTime.MinValue;
                    DateTime.TryParse(reqRespData.StartDate, out startDate);
                    DateTime.TryParse(reqRespData.EndDate, out endDate);
                    reqRespData.StDate = startDate;
                    reqRespData.EnDate = endDate;
                    log.LogInformation($"PerformRestore: Start date : {reqRespData.StDate.ToString("MM/dd/yyyy")}, End date {reqRespData.EnDate.ToString("MM/dd/yyyy")}. Proceeding with restore process ...");
                    if (!String.IsNullOrEmpty(reqRespData.ContainerName))
                    {
                        log.LogInformation($"PerformRestore: Container Name : {reqRespData.ContainerName}");
                    }
                    await _restoreBackup.Run(reqRespData);

                    // Update the status of the restore request to completed
                    reqRespData.Status  = Constants.RESTORE_STATUS_COMPLETED;
                    reqRespData.EndTime = DateTime.Now.ToString();
                    stopWatch.Stop();
                    reqRespData.ExecutionTime = DateTimeUtil.getTimeString(stopWatch.Elapsed);
                    await _restoreTable.UpdateRestoreRequest(reqRespData);
                }
            }
            catch (Exception ex)
            {
                log.LogError($"PerformRestoreAsync: Exception occurred while processing message. Exception: {@ex.ToString()}");
                // Update the status of the restore request to exception
                if (reqRespData != null)
                {
                    reqRespData.Status           = Constants.RESTORE_STATUS_FAILED;
                    reqRespData.ExceptionMessage = $"PerformRestoreAsync: Encountered Exception: {@ex.ToString()}";
                    reqRespData.EndTime          = DateTime.Now.ToString();
                    stopWatch.Stop();
                    reqRespData.ExecutionTime = DateTimeUtil.getTimeString(stopWatch.Elapsed);

                    await _restoreTable.UpdateRestoreRequest(reqRespData);
                }
                ;
            }
            stopWatch = null;
            log.LogInformation($"PerformRestoreAsync: Completed execution at: {DateTime.Now}");
        }