Exemplo n.º 1
0
        private static async Task SaveObjectAsync(GetObjectResponse response, DownloadObjectInfo info)
        {
            response.WriteObjectProgressEvent += Response_WriteObjectProgressEvent;
            string checkedFilePath = CheckFilePath(info);

            await response.WriteResponseStreamToFileAsync(checkedFilePath, false, new CancellationToken());

            DownloadSuccess?.Invoke($"Backup downloaded {info.ObjectKey} to {Path.Combine(info.DownloadDirectory, checkedFilePath)}");
        }
Exemplo n.º 2
0
        /// <summary>
        /// Issue a request to get Glacier inventory or process existing request
        /// </summary>
        public static async Task <GlacierResult> GetGlacierInventoryAsync(Settings settings)
        {
            #region pseudocode
            // Is there an inventory file?
            // Yes: return Inventory and issue new request
            // Not found:
            //   Is an inventory request issued?
            //      Yes: get request details
            //      No: Issue request and save SNS topic, Job ID, Queue URL
            // Poll topic for response
            // Poll Message received?
            //    Yes: serialize inventory to file and return
            //    No: return details of inventory request (in progress)
            #endregion
            try
            {
                Topic topic       = GetExistingTopic(InventoryTopicFileName);
                var   updateIsDue = IsInventoryUpdateDue(settings);
                if (topic == null && updateIsDue)
                {
                    // Issue new request and serialize topic details to global file
                    topic = await SetupTopicAndSubscriptionsAsync(InventoryTopicFileName, GetTempDirectory(), settings.AWSGlacierRegion.SystemName, null, InventoryFileName);

                    topic.Type        = "inventory-retrieval";
                    topic.Description = "This job is to download a vault inventory";
                    InitiateGlacierJob(topic);
                    settings.InventoryUpdateRequested = DateTime.Now;
                    SaveSettingsAsync(settings);
                    return(topic.Status); // only requested - no need to process yet
                }
                if (!updateIsDue)
                {
                    return(GlacierResult.NoJob);
                }

                var result = await ProcessQueueAsync(topic);

                Debug.WriteLine("ProcessQueue result: " + result);
                if (result == GlacierResult.Completed)
                {
                    DownloadSuccess?.Invoke("Glacier Inventory was updated");
                }

                return(topic.Status);
            }
            catch (Exception ex)
            {
                BackupError?.Invoke(ex.Message);
                return(GlacierResult.Error);
            }
        }
Exemplo n.º 3
0
        public static GlacierResult ProcessQueue(Topic topic)
        {
            // Check for notifications on topic and process any message
            try
            {
                var settings = SettingsManager.GetSettings();
                using (var client = new AmazonGlacierClient(
                           settings.AWSAccessKeyID,
                           settings.AWSSecretAccessKey,
                           RegionEndpoint.GetBySystemName(settings.AWSS3Region.SystemName)))
                {
                    var receiveMessageRequest = new ReceiveMessageRequest {
                        QueueUrl = topic.QueueUrl, MaxNumberOfMessages = 1
                    };
                    var sqsClient = new AmazonSQSClient(settings.AWSAccessKeyID, settings.AWSSecretAccessKey, RegionEndpoint.GetBySystemName(settings.AWSS3Region.SystemName));
                    var receiveMessageResponse = sqsClient.ReceiveMessage(receiveMessageRequest);
                    if (receiveMessageResponse.Messages.Count == 0)
                    {
                        topic.Status = GlacierResult.Incomplete;
                        SaveTopicFile(topic);
                        return(topic.Status);
                    }

                    // Process message
                    string status = GetResponseStatus(receiveMessageResponse);
                    if (string.Equals(status, GlacierUtils.JOB_STATUS_SUCCEEDED, StringComparison.InvariantCultureIgnoreCase))
                    {
                        DownloadGlacierJobOutput(topic.JobId, client, settings.AWSGlacierVault, topic.GetOutputFile());
                        Debug.WriteLine($"Downloaded job output to {topic.GetOutputFile()}");
                        if (topic.ArchiveId != null)
                        {
                            DownloadSuccess?.Invoke($"Glacier archive was downloaded to {topic.GetOutputFile()}");
                        }
                        DeleteTopic(topic);
                        return(GlacierResult.Completed);
                    }
                    else if (string.Equals(status, GlacierUtils.JOB_STATUS_FAILED, StringComparison.InvariantCultureIgnoreCase))
                    {
                        DownloadError?.Invoke("Job failed, cannot download the file");
                        DeleteTopic(topic);
                        return(GlacierResult.JobFailed);
                    }
                    else if (string.Equals(status, GlacierUtils.JOB_STATUS_INPROGRESS, StringComparison.InvariantCultureIgnoreCase))
                    {
                        DownloadWarning?.Invoke("Job in progress, Queue ARN: " + topic.QueueARN);
                        DeleteTopic(topic);
                        return(GlacierResult.JobInProgress);
                    }
                    else
                    {
                        DeleteTopic(topic);
                        return(GlacierResult.Error);
                    }
                }
            }
            catch (AmazonServiceException azex)
            {
                // Handle specific potential errors here
                Debug.WriteLine("AmazonServiceException " + azex.Message);

                if (azex.StatusCode == System.Net.HttpStatusCode.Forbidden)
                {
                    // Invalid credentials
                    BackupError?.Invoke("Invalid AWS credentials were provided while connecting");
                    return(GlacierResult.Incomplete);
                }
                if (azex.InnerException != null &&
                    azex.InnerException is System.Net.WebException &&
                    ((System.Net.WebException)azex.InnerException).Status == System.Net.WebExceptionStatus.NameResolutionFailure)
                {
                    // Not connected to internet
                    BackupError?.Invoke("Network connection failure");
                    return(GlacierResult.Incomplete);
                }
                if (azex.InnerException != null &&
                    azex.InnerException is System.Net.WebException)
                {
                    // Network errors
                    BackupError?.Invoke($"A network error occurred ({((System.Net.WebException)azex.InnerException).Status})");
                    return(GlacierResult.Incomplete);
                }
                if (azex.StatusCode == System.Net.HttpStatusCode.BadRequest
                    //&& topic.Status == GlacierResult.JobRequested
                    && azex.Message.Contains("The specified queue does not exist") &&
                    DateTime.Now - topic.DateRequested < new TimeSpan(24, 0, 0))
                {
                    // Job was recently requested and the queue has not been created yet
                    Debug.WriteLine("Job request may be in progress");
                    return(GlacierResult.JobRequested);
                }

                // TODO Check expiry?
                // Glacier ref: "A job ID will not expire for at least 24 hours after Amazon Glacier completes the job."
                DeleteTopic(topic);
                BackupWarning?.Invoke("An AWS Glacier job has expired, a new job will be issued");

                // Reissue expired job
                InitiateGlacierJob(topic);
                return(topic.Status);
            }
            catch (Exception ex)
            {
                DeleteTopic(topic);
                throw ex;
            }
        }