Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions generator/.DevConfigs/9d07dc1e-d82d-4f94-8700-c7b57f872044.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"services": [
{
"serviceName": "S3",
"type": "minor",
"changeLogMessages": [
"Created new UploadDirectoryWithResponseAsync method on the Amazon.S3.Transfer.TransferUtility class."
]
}
]
}
11 changes: 11 additions & 0 deletions generator/.DevConfigs/9d07dc1e-d82d-4f94-8700-c7b57f872124.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"services": [
{
"serviceName": "S3",
"type": "minor",
"changeLogMessages": [
"Added UploadDirectoryInitiatedEvent, UploadDirectoryCompletedEvent, and UploadDirectoryFailedEvent for Amazon.S3.Transfer.TransferUtility.UploadDirectory."
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,43 @@ internal partial class UploadDirectoryCommand : BaseCommand<TransferUtilityUploa
int _numberOfFilesUploaded;
int _numberOfFilesSuccessfullyUploaded;
long _totalBytes;
long _transferredBytes;
long _transferredBytes;

#region Event Firing Methods

private void FireTransferInitiatedEvent()
{
var eventArgs = new UploadDirectoryInitiatedEventArgs(
_request,
_totalNumberOfFiles,
_totalBytes);
_request.OnRaiseUploadDirectoryInitiatedEvent(eventArgs);
}

private void FireTransferCompletedEvent(TransferUtilityUploadDirectoryResponse response)
{
var eventArgs = new UploadDirectoryCompletedEventArgs(
_request,
response,
_numberOfFilesSuccessfullyUploaded,
_totalNumberOfFiles,
Interlocked.Read(ref _transferredBytes),
_totalBytes);
_request.OnRaiseUploadDirectoryCompletedEvent(eventArgs);
}

private void FireTransferFailedEvent()
{
var eventArgs = new UploadDirectoryFailedEventArgs(
_request,
_numberOfFilesSuccessfullyUploaded,
_totalNumberOfFiles,
Interlocked.Read(ref _transferredBytes),
_totalBytes);
_request.OnRaiseUploadDirectoryFailedEvent(eventArgs);
}

#endregion

internal UploadDirectoryCommand(TransferUtility utility, TransferUtilityConfig config, TransferUtilityUploadDirectoryRequest request)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,38 +31,51 @@ internal partial class UploadDirectoryCommand : BaseCommand<TransferUtilityUploa

public override async Task<TransferUtilityUploadDirectoryResponse> ExecuteAsync(CancellationToken cancellationToken)
{
// Step 1: Setup paths and discover files
string prefix = GetKeyPrefix();
string basePath = new DirectoryInfo(this._request.Directory).FullName;
try
{
// Step 1: Setup paths and discover files
string prefix = GetKeyPrefix();
string basePath = new DirectoryInfo(this._request.Directory).FullName;

_logger.DebugFormat("UploadDirectoryCommand.ExecuteAsync: Starting - BasePath={0}, Prefix={1}, UploadFilesConcurrently={2}, ConcurrentServiceRequests={3}",
basePath, prefix, UploadFilesConcurrently, this._config.ConcurrentServiceRequests);
_logger.DebugFormat("UploadDirectoryCommand.ExecuteAsync: Starting - BasePath={0}, Prefix={1}, UploadFilesConcurrently={2}, ConcurrentServiceRequests={3}",
basePath, prefix, UploadFilesConcurrently, this._config.ConcurrentServiceRequests);

// Step 2: Discover files to upload
string[] filePaths = await DiscoverFilesAsync(basePath, cancellationToken)
.ConfigureAwait(false);
// Step 2: Discover files to upload
string[] filePaths = await DiscoverFilesAsync(basePath, cancellationToken)
.ConfigureAwait(false);

this._totalNumberOfFiles = filePaths.Length;
_logger.DebugFormat("UploadDirectoryCommand.ExecuteAsync: Discovered {0} file(s) to upload. TotalBytes={1}",
_totalNumberOfFiles, _totalBytes);
this._totalNumberOfFiles = filePaths.Length;
_logger.DebugFormat("UploadDirectoryCommand.ExecuteAsync: Discovered {0} file(s) to upload. TotalBytes={1}",
_totalNumberOfFiles, _totalBytes);

// Step 3: Setup resources and execute uploads
using (var resources = CreateUploadResources(cancellationToken))
{
await ExecuteParallelUploadsAsync(
filePaths,
basePath,
prefix,
resources,
cancellationToken)
.ConfigureAwait(false);
}
FireTransferInitiatedEvent();

// Step 4: Build and return response
_logger.DebugFormat("UploadDirectoryCommand.ExecuteAsync: Completed - FilesSuccessfullyUploaded={0}, FilesFailed={1}",
_numberOfFilesSuccessfullyUploaded, _errors.Count);

return BuildResponse();
// Step 3: Setup resources and execute uploads
using (var resources = CreateUploadResources(cancellationToken))
{
await ExecuteParallelUploadsAsync(
filePaths,
basePath,
prefix,
resources,
cancellationToken)
.ConfigureAwait(false);
}

// Step 4: Build and return response
_logger.DebugFormat("UploadDirectoryCommand.ExecuteAsync: Completed - FilesSuccessfullyUploaded={0}, FilesFailed={1}",
_numberOfFilesSuccessfullyUploaded, _errors.Count);

var response = BuildResponse();
FireTransferCompletedEvent(response);
return response;
}
catch
{
FireTransferFailedEvent();
throw;
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,33 @@ public FailurePolicy FailurePolicy
set { this.failurePolicy = value; }
}

/// <summary>
/// Occurs when the upload directory operation is initiated.
/// </summary>
/// <remarks>
/// This event is raised before any files are uploaded, providing information about
/// the total number of files and bytes that will be uploaded.
/// </remarks>
public event EventHandler<UploadDirectoryInitiatedEventArgs> UploadDirectoryInitiatedEvent;

/// <summary>
/// Occurs when the upload directory operation completes successfully.
/// </summary>
/// <remarks>
/// This event is raised after all files have been processed (successfully or with failures),
/// providing the final response and statistics.
/// </remarks>
public event EventHandler<UploadDirectoryCompletedEventArgs> UploadDirectoryCompletedEvent;

/// <summary>
/// Occurs when the upload directory operation fails.
/// </summary>
/// <remarks>
/// This event is raised when the entire operation fails (not individual file failures).
/// Individual file failures are reported through <see cref="ObjectUploadFailedEvent"/>.
/// </remarks>
public event EventHandler<UploadDirectoryFailedEventArgs> UploadDirectoryFailedEvent;

/// <summary>
/// Occurs when an individual object fails to upload during an UploadDirectory operation.
/// </summary>
Expand All @@ -72,6 +99,33 @@ public FailurePolicy FailurePolicy
/// </example>
public event EventHandler<ObjectUploadFailedEventArgs> ObjectUploadFailedEvent;

/// <summary>
/// Internal helper used by the transfer implementation to raise the <see cref="UploadDirectoryInitiatedEvent"/>.
/// </summary>
/// <param name="args">The event args.</param>
internal void OnRaiseUploadDirectoryInitiatedEvent(UploadDirectoryInitiatedEventArgs args)
{
UploadDirectoryInitiatedEvent?.Invoke(this, args);
}

/// <summary>
/// Internal helper used by the transfer implementation to raise the <see cref="UploadDirectoryCompletedEvent"/>.
/// </summary>
/// <param name="args">The event args.</param>
internal void OnRaiseUploadDirectoryCompletedEvent(UploadDirectoryCompletedEventArgs args)
{
UploadDirectoryCompletedEvent?.Invoke(this, args);
}

/// <summary>
/// Internal helper used by the transfer implementation to raise the <see cref="UploadDirectoryFailedEvent"/>.
/// </summary>
/// <param name="args">The event args.</param>
internal void OnRaiseUploadDirectoryFailedEvent(UploadDirectoryFailedEventArgs args)
{
UploadDirectoryFailedEvent?.Invoke(this, args);
}

/// <summary>
/// Internal helper used by the transfer implementation to raise the <see cref="ObjectUploadFailedEvent"/>.
/// </summary>
Expand Down Expand Up @@ -421,6 +475,157 @@ public UploadDirectoryFileRequestArgs(TransferUtilityUploadRequest request)
public TransferUtilityUploadRequest UploadRequest { get; set; }
}

/// <summary>
/// Provides data for <see cref="TransferUtilityUploadDirectoryRequest.UploadDirectoryInitiatedEvent"/>.
/// </summary>
public class UploadDirectoryInitiatedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="UploadDirectoryInitiatedEventArgs"/> class.
/// </summary>
/// <param name="request">The upload directory request.</param>
/// <param name="totalFiles">The total number of files to upload.</param>
/// <param name="totalBytes">The total number of bytes to upload.</param>
internal UploadDirectoryInitiatedEventArgs(
TransferUtilityUploadDirectoryRequest request,
long totalFiles,
long totalBytes)
{
Request = request;
TotalFiles = totalFiles;
TotalBytes = totalBytes;
}

/// <summary>
/// Gets the upload directory request.
/// </summary>
public TransferUtilityUploadDirectoryRequest Request { get; private set; }

/// <summary>
/// Gets the total number of files to upload.
/// </summary>
public long TotalFiles { get; private set; }

/// <summary>
/// Gets the total number of bytes to upload.
/// </summary>
public long TotalBytes { get; private set; }
}

/// <summary>
/// Provides data for <see cref="TransferUtilityUploadDirectoryRequest.UploadDirectoryCompletedEvent"/>.
/// </summary>
public class UploadDirectoryCompletedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="UploadDirectoryCompletedEventArgs"/> class.
/// </summary>
/// <param name="request">The upload directory request.</param>
/// <param name="response">The upload directory response.</param>
/// <param name="transferredFiles">The number of files successfully uploaded.</param>
/// <param name="totalFiles">The total number of files attempted.</param>
/// <param name="transferredBytes">The number of bytes transferred.</param>
/// <param name="totalBytes">The total number of bytes.</param>
internal UploadDirectoryCompletedEventArgs(
TransferUtilityUploadDirectoryRequest request,
TransferUtilityUploadDirectoryResponse response,
long transferredFiles,
long totalFiles,
long transferredBytes,
long totalBytes)
{
Request = request;
Response = response;
TransferredFiles = transferredFiles;
TotalFiles = totalFiles;
TransferredBytes = transferredBytes;
TotalBytes = totalBytes;
}

/// <summary>
/// Gets the upload directory request.
/// </summary>
public TransferUtilityUploadDirectoryRequest Request { get; private set; }

/// <summary>
/// Gets the upload directory response.
/// </summary>
public TransferUtilityUploadDirectoryResponse Response { get; private set; }

/// <summary>
/// Gets the number of files successfully uploaded.
/// </summary>
public long TransferredFiles { get; private set; }

/// <summary>
/// Gets the total number of files attempted.
/// </summary>
public long TotalFiles { get; private set; }

/// <summary>
/// Gets the number of bytes transferred.
/// </summary>
public long TransferredBytes { get; private set; }

/// <summary>
/// Gets the total number of bytes.
/// </summary>
public long TotalBytes { get; private set; }
}

/// <summary>
/// Provides data for <see cref="TransferUtilityUploadDirectoryRequest.UploadDirectoryFailedEvent"/>.
/// </summary>
public class UploadDirectoryFailedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="UploadDirectoryFailedEventArgs"/> class.
/// </summary>
/// <param name="request">The upload directory request.</param>
/// <param name="transferredFiles">The number of files successfully uploaded before failure.</param>
/// <param name="totalFiles">The total number of files attempted.</param>
/// <param name="transferredBytes">The number of bytes transferred before failure.</param>
/// <param name="totalBytes">The total number of bytes.</param>
internal UploadDirectoryFailedEventArgs(
TransferUtilityUploadDirectoryRequest request,
long transferredFiles,
long totalFiles,
long transferredBytes,
long totalBytes)
{
Request = request;
TransferredFiles = transferredFiles;
TotalFiles = totalFiles;
TransferredBytes = transferredBytes;
TotalBytes = totalBytes;
}

/// <summary>
/// Gets the upload directory request.
/// </summary>
public TransferUtilityUploadDirectoryRequest Request { get; private set; }

/// <summary>
/// Gets the number of files successfully uploaded before failure.
/// </summary>
public long TransferredFiles { get; private set; }

/// <summary>
/// Gets the total number of files attempted.
/// </summary>
public long TotalFiles { get; private set; }

/// <summary>
/// Gets the number of bytes transferred before failure.
/// </summary>
public long TransferredBytes { get; private set; }

/// <summary>
/// Gets the total number of bytes.
/// </summary>
public long TotalBytes { get; private set; }
}

/// <summary>
/// Provides data for <see cref="TransferUtilityUploadDirectoryRequest.ObjectUploadFailedEvent"/>
/// which is raised when an individual object fails to upload during an
Expand Down
Loading