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)}"); }
/// <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); } }
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; } }