Skip to content

Commit

Permalink
Dotnet transferutil update (awsdocs#3955)
Browse files Browse the repository at this point in the history
* Update TransferUtility MVP Tests to use XUnit

* Updated UI for TransferUtility MVP

* Fixed linter error.

* Incorporating feedback.

* Fixing linter error.

Co-authored-by: Steven Meyer <[email protected]>
  • Loading branch information
irenepsmith and meyertst-aws authored Nov 18, 2022
1 parent c4eabd4 commit 2c45d87
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransferUtilityBasics", "TransferUtilityBasics\TransferUtilityBasics.csproj", "{C8AC1563-7AE9-4BFB-9287-EFCE9B199A28}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransferUtilityBasics", "TransferUtilityBasics\TransferUtilityBasics.csproj", "{C8AC1563-7AE9-4BFB-9287-EFCE9B199A28}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransferUtilityBasicsTests", "TransferUtilityBasicsTests\TransferUtilityBasicsTests.csproj", "{D13D8EAB-5F80-4AEA-BC16-4A5605F3F0D0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransferUtilityBasicsTests", "TransferUtilityBasicsTests\TransferUtilityBasicsTests.csproj", "{09A35C18-8545-4F25-AECA-E315F7057676}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -17,10 +17,10 @@ Global
{C8AC1563-7AE9-4BFB-9287-EFCE9B199A28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C8AC1563-7AE9-4BFB-9287-EFCE9B199A28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C8AC1563-7AE9-4BFB-9287-EFCE9B199A28}.Release|Any CPU.Build.0 = Release|Any CPU
{D13D8EAB-5F80-4AEA-BC16-4A5605F3F0D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D13D8EAB-5F80-4AEA-BC16-4A5605F3F0D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D13D8EAB-5F80-4AEA-BC16-4A5605F3F0D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D13D8EAB-5F80-4AEA-BC16-4A5605F3F0D0}.Release|Any CPU.Build.0 = Release|Any CPU
{09A35C18-8545-4F25-AECA-E315F7057676}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09A35C18-8545-4F25-AECA-E315F7057676}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09A35C18-8545-4F25-AECA-E315F7057676}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09A35C18-8545-4F25-AECA-E315F7057676}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,35 @@

// This Amazon S3 client uses the default user credentials
// defined for this computer.
using Microsoft.Extensions.Configuration;

IAmazonS3 client = new AmazonS3Client();
var transferUtil = new TransferUtility(client);

// Change the following values to an Amazon S3 bucket that
// exists in your AWS account.
var bucketName = "doc-example-bucket1";
IConfiguration _configuration;

_configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("settings.json") // Load test settings from JSON file.
.AddJsonFile("settings.local.json",
true) // Optionally load local settings.
.Build();

// Edit the values in settings.json to use an S3 bucket and files that
// exist on your AWS account and on the local computer where you
// run this scenario.
var bucketName = _configuration["BucketName"];
var localPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\TransferFolder";

DisplayInstructions();

PressEnter();

Console.WriteLine();

// Upload a single file to an S3 bucket.
var fileToUpload = "UploadTest.docx";
DisplayTitle("Upload a single file");

var fileToUpload = _configuration["FileToUpload"];
Console.WriteLine($"Uploading {fileToUpload} to the S3 bucket, {bucketName}.");

var success = await TransferMethods.UploadSingleFileAsync(transferUtil, bucketName, fileToUpload, localPath);
Expand All @@ -31,14 +45,18 @@
PressEnter();

// Upload a local directory to an S3 bucket.
var keyPrefix = "UploadFolder";
DisplayTitle("Upload all files from a local directory");
Console.WriteLine("Upload all the files in a local folder to an S3 bucket.");
const string keyPrefix = "UploadFolder";
var uploadPath = $"{localPath}\\UploadFolder";

Console.WriteLine($"Uploading the files in {uploadPath} to {bucketName}");
Console.WriteLine($"{uploadPath} contains the following files:");
DisplayTitle($"{uploadPath} files");
DisplayLocalFiles(uploadPath);
Console.WriteLine();

PressEnter();

success = await TransferMethods.UploadFullDirectoryAsync(transferUtil, bucketName, keyPrefix, uploadPath);
if (success)
{
Expand All @@ -50,9 +68,11 @@

PressEnter();


// Download a single file from an S3 bucket.
var keyName = "FileToDownload.docx";
DisplayTitle("Download a single file");
Console.WriteLine("Now we will download a single file from an S3 bucket.");

var keyName = _configuration["FileToDownload"];

Console.WriteLine($"Downloading {keyName} from {bucketName}.");

Expand All @@ -65,8 +85,9 @@
PressEnter();

// Download the contents of a directory from an S3 bucket.
var s3Path = "DownloadFolder";
var downloadPath = $"{localPath}\\DownloadFolder";
DisplayTitle("Download the contents of an S3 bucket");
var s3Path = _configuration["S3Path"];
var downloadPath = $"{localPath}\\{s3Path}";

Console.WriteLine($"Downloading the contents of {bucketName}\\{s3Path}");
Console.WriteLine($"{bucketName}\\{s3Path} contains the following files:");
Expand All @@ -77,49 +98,62 @@
if (success)
{
Console.WriteLine($"Downloaded the files in {bucketName} to {downloadPath}.");
Console.WriteLine($"{downloadPath} now contains the fillowing files:");
Console.WriteLine($"{downloadPath} now contains the following files:");
DisplayLocalFiles(downloadPath);
}

Console.WriteLine("\nThe TransferUtility Basics application has completed.");
PressEnter();

static void DisplayInstructions()
// Displays the title for a section of the scenario.
static void DisplayTitle(string titleText)
{
var sepBar = new string('-', 80);
var sepBar = new string('-', Console.WindowWidth);

Console.Clear();
Console.WriteLine(sepBar);
Console.WriteLine(CenterText("Amazon S3 Transfer Utility Basics"));
Console.WriteLine(CenterText(titleText));
Console.WriteLine(sepBar);
}

// Displays a description of the actions to be performed by the scenario.
static void DisplayInstructions()
{
var sepBar = new string('-', Console.WindowWidth);

DisplayTitle("Amazon S3 Transfer Utility Basics");
Console.WriteLine("This program shows how to use the Amazon S3 Transfer Utility.");
Console.WriteLine("It performs the following actions:");
Console.WriteLine("\t1. Upload a single object to an S3 bucket.");
Console.WriteLine("\t2. Upload all an entire directory from the local computer to an\n\t S3 bucket.");
Console.WriteLine("\t2. Upload an entire directory from the local computer to an\n\t S3 bucket.");
Console.WriteLine("\t3. Download a single object from an S3 bucket.");
Console.WriteLine("\t4. Download the objects in an S3 bucket to a local directory.");
Console.WriteLine($"\n{sepBar}");
}

// Pauses the scenario.
static void PressEnter()
{
Console.WriteLine("Press <Enter> to continue.");
_ = Console.ReadLine();
Console.WriteLine("\n");
}

// Returns the string textToCenter, padded on the left with spaces
// that center the text on the console display.
static string CenterText(string textToCenter)
{
var centeredText = new StringBuilder();
centeredText.Append(new string(' ', (int)(80 - textToCenter.Length) / 2));
var screenWidth = Console.WindowWidth;
centeredText.Append(new string(' ', (int)(screenWidth - textToCenter.Length) / 2));
centeredText.Append(textToCenter);
return centeredText.ToString();
}

// Displays a list of file names included in the specified path.
static void DisplayLocalFiles(string localPath)
{
var fileList = Directory.GetFiles(localPath);
if (fileList is not null)
if (fileList.Length > 0)
{
foreach (var fileName in fileList)
{
Expand All @@ -128,6 +162,7 @@ static void DisplayLocalFiles(string localPath)
}
}

// Displays a list of the files in the specified S3 bucket and prefix.
static async Task DisplayBucketFiles(IAmazonS3 client, string bucketName, string s3Path)
{
ListObjectsV2Request request = new()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,24 @@

namespace TransferUtilityBasics
{
/// <summary>
/// Class methods perform actions for the TransferUtility Scenario
/// </summary>
public class TransferMethods
{
// snippet-start:[S3.dotnetv3.TransferUtilityBasics.DownloadSingleFileAsync]

/// <summary>
/// Download a single file from an S3 bucket to the local computer.
/// </summary>
/// <param name="transferUtil">The transfer initialized TransferUtility
/// object.</param>
/// <param name="bucketName">The name of the S3 bucket containing the
/// file to download.</param>
/// <param name="keyName">The name of the file to download.</param>
/// <param name="localPath">The path on the local computer where the
/// downloaded file will be saved.</param>
/// <returns>A Boolean value indicating the results of the action.</returns>
public static async Task<bool> DownloadSingleFileAsync(
TransferUtility transferUtil,
string bucketName,
Expand All @@ -19,25 +34,39 @@ await transferUtil.DownloadAsync(new TransferUtilityDownloadRequest
FilePath = $"{localPath}\\{keyName}",
});

if (File.Exists($"{localPath}\\{keyName}"))
{
return true;
}
else
{
return false;
}
return (File.Exists($"{localPath}\\{keyName}"));
}

// snippet-end:[S3.dotnetv3.TransferUtilityBasics.DownloadSingleFileAsync]

// snippet-start:[S3.dotnetv3.TransferUtilityBasics.DownloadS3DirectoryAsync]

/// <summary>
/// Downloads the contents of a directory in an S3 bucket to a
/// directory on the local computer.
/// </summary>
/// <param name="transferUtil">The transfer initialized TransferUtility
/// object.</param>
/// <param name="bucketName">The bucket containing the files to download.</param>
/// <param name="s3Path">The S3 directory where the files are located.</param>
/// <param name="localPath">The local path to which the files will be
/// saved.</param>
/// <returns>A Boolean value representing the success of the action.</returns>
public static async Task<bool> DownloadS3DirectoryAsync(
TransferUtility transferUtil,
string bucketName,
string s3Path,
string localPath)
{
int fileCount = 0;

// If the directory doesn't exist, it will be created.
if (Directory.Exists(s3Path))
{
var files = Directory.GetFiles(localPath);
fileCount = files.Length;
}

await transferUtil.DownloadDirectoryAsync(new TransferUtilityDownloadDirectoryRequest
{
BucketName = bucketName,
Expand All @@ -47,17 +76,36 @@ await transferUtil.DownloadDirectoryAsync(new TransferUtilityDownloadDirectoryRe

if (Directory.Exists(localPath))
{
return true;
}
else
{
var files = Directory.GetFiles(localPath);
if (files.Length > fileCount)
{
return true;
}

// No change in the number of files. Assume
// the download failed.
return false;
}

// The local directory doesn't exist. No files
// were downloaded.
return false;
}

// snippet-end:[S3.dotnetv3.TransferUtilityBasics.DownloadS3DirectoryAsync]

// snippet-start:[S3.dotnetv3.TransferUtilityBasics.UploadSingleFileAsync]

/// <summary>
/// Uploads a single file from the local computer to an S3 bucket.
/// </summary>
/// <param name="transferUtil">The transfer initialized TransferUtility
/// object.</param>
/// <param name="bucketName">The name of the S3 bucket where the file
/// will be stored.</param>
/// <param name="fileName">The name of the file to upload.</param>
/// <param name="localPath">The local path where the file is stored.</param>
/// <returns>A boolean value indicating the success of the action.</returns>
public static async Task<bool> UploadSingleFileAsync(
TransferUtility transferUtil,
string bucketName,
Expand Down Expand Up @@ -93,6 +141,20 @@ await transferUtil.UploadAsync(new TransferUtilityUploadRequest
// snippet-end:[S3.dotnetv3.TransferUtilityBasics.UploadSingleFileAsync]

// snippet-start:[S3.dotnetv3.TransferUtilityBasics.UploadFullDirectoryAsync]

/// <summary>
/// Uploads all the files in a local directory to a directory in an S3
/// bucket.
/// </summary>
/// <param name="transferUtil">The transfer initialized TransferUtility
/// object.</param>
/// <param name="bucketName">The name of the S3 bucket where the files
/// will be stored.</param>
/// <param name="keyPrefix">The key prefix is the S3 directory where
/// the files will be stored.</param>
/// <param name="localPath">The local directory that contains the files
/// to be uploaded.</param>
/// <returns>A Boolean value representing the success of the action.</returns>
public static async Task<bool> UploadFullDirectoryAsync(
TransferUtility transferUtil,
string bucketName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,21 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.Core" Version="3.7.12.10" />
<PackageReference Include="AWSSDK.S3" Version="3.7.9.27" />
<PackageReference Include="AWSSDK.Core" Version="3.7.100.16" />
<PackageReference Include="AWSSDK.S3" Version="3.7.101.16" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
</ItemGroup>

<ItemGroup>
<Content Include="settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="settings.*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<DependentUpon>settings.json</DependentUpon>
</Content>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"BucketName": "doc-example-bucket",
"FileToDownload": "Download.txt",
"FileToUpload": "Upload.txt",
"S3Path": "DownloadPath"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

global using Xunit;
global using Amazon.S3;
global using Amazon.S3.Transfer;
global using TransferUtilityBasics;
global using Microsoft.Extensions.Configuration;
Loading

0 comments on commit 2c45d87

Please sign in to comment.