Skip to content
Closed
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/433a9a6d-b8ea-4676-b763-70711e8288e2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"services": [
{
"serviceName": "S3",
"type": "minor",
"changeLogMessages": [
"Added progress tracking events to simple upload"
]
}
]
}
11 changes: 11 additions & 0 deletions generator/.DevConfigs/433a9a6d-b8ea-4676-b763-70711e8288e6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"services": [
{
"serviceName": "S3",
"type": "patch",
"changeLogMessages": [
"Added CompleteMultipartUploadResponse to TransferUtilityUploadResponse mapping"
]
}
]
}
61 changes: 61 additions & 0 deletions sdk/src/Services/S3/Custom/Transfer/Internal/ResponseMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,67 @@ internal static TransferUtilityUploadResponse MapPutObjectResponse(PutObjectResp

return response;
}

/// <summary>
/// Maps a CompleteMultipartUploadResponse to TransferUtilityUploadResponse.
/// Uses the field mappings defined in mapping.json "Conversion" -> "CompleteMultipartResponse" -> "UploadResponse".
/// </summary>
/// <param name="source">The CompleteMultipartUploadResponse to map from</param>
/// <returns>A new TransferUtilityUploadResponse with mapped fields</returns>
internal static TransferUtilityUploadResponse MapCompleteMultipartUploadResponse(CompleteMultipartUploadResponse source)
{
if (source == null)
return null;

var response = new TransferUtilityUploadResponse();

// Map all fields as defined in mapping.json "Conversion" -> "CompleteMultipartResponse" -> "UploadResponse"
if (source.IsSetBucketKeyEnabled())
response.BucketKeyEnabled = source.BucketKeyEnabled.GetValueOrDefault();

if (source.IsSetChecksumCRC32())
response.ChecksumCRC32 = source.ChecksumCRC32;

if (source.IsSetChecksumCRC32C())
response.ChecksumCRC32C = source.ChecksumCRC32C;

if (source.IsSetChecksumCRC64NVME())
response.ChecksumCRC64NVME = source.ChecksumCRC64NVME;

if (source.IsSetChecksumSHA1())
response.ChecksumSHA1 = source.ChecksumSHA1;

if (source.IsSetChecksumSHA256())
response.ChecksumSHA256 = source.ChecksumSHA256;

if (source.ChecksumType != null)
response.ChecksumType = source.ChecksumType;

if (source.IsSetETag())
response.ETag = source.ETag;

if (source.Expiration != null)
response.Expiration = source.Expiration;

if (source.IsSetRequestCharged())
response.RequestCharged = source.RequestCharged;

if (source.ServerSideEncryptionMethod != null)
response.ServerSideEncryptionMethod = source.ServerSideEncryptionMethod;

if (source.IsSetServerSideEncryptionKeyManagementServiceKeyId())
response.ServerSideEncryptionKeyManagementServiceKeyId = source.ServerSideEncryptionKeyManagementServiceKeyId;

if (source.IsSetVersionId())
response.VersionId = source.VersionId;

// Copy response metadata
response.ResponseMetadata = source.ResponseMetadata;
response.ContentLength = source.ContentLength;
response.HttpStatusCode = source.HttpStatusCode;

return response;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,18 @@ internal partial class SimpleUploadCommand : BaseCommand
IAmazonS3 _s3Client;
TransferUtilityConfig _config;
TransferUtilityUploadRequest _fileTransporterRequest;
long _totalTransferredBytes;
private readonly long _contentLength;

internal SimpleUploadCommand(IAmazonS3 s3Client, TransferUtilityConfig config, TransferUtilityUploadRequest fileTransporterRequest)
{
this._s3Client = s3Client;
this._config = config;
this._fileTransporterRequest = fileTransporterRequest;

// Cache content length immediately while stream is accessible to avoid ObjectDisposedException in failure scenarios
this._contentLength = this._fileTransporterRequest.ContentLength;

var fileName = fileTransporterRequest.FilePath;
}

Expand Down Expand Up @@ -103,9 +109,48 @@ private PutObjectRequest ConstructRequest()

private void PutObjectProgressEventCallback(object sender, UploadProgressArgs e)
{
var progressArgs = new UploadProgressArgs(e.IncrementTransferred, e.TransferredBytes, e.TotalBytes,
e.CompensationForRetry, _fileTransporterRequest.FilePath);
// Keep track of the total transferred bytes so that we can also return this value in case of failure
long transferredBytes = Interlocked.Add(ref _totalTransferredBytes, e.IncrementTransferred - e.CompensationForRetry);

var progressArgs = new UploadProgressArgs(e.IncrementTransferred, transferredBytes, _contentLength,
e.CompensationForRetry, _fileTransporterRequest.FilePath, _fileTransporterRequest);
this._fileTransporterRequest.OnRaiseProgressEvent(progressArgs);
}

private void FireTransferInitiatedEvent()
{
var initiatedArgs = new UploadInitiatedEventArgs(
request: _fileTransporterRequest,
filePath: _fileTransporterRequest.FilePath,
totalBytes: _contentLength
);

_fileTransporterRequest.OnRaiseTransferInitiatedEvent(initiatedArgs);
}

private void FireTransferCompletedEvent(TransferUtilityUploadResponse response)
{
var completedArgs = new UploadCompletedEventArgs(
request: _fileTransporterRequest,
response: response,
filePath: _fileTransporterRequest.FilePath,
transferredBytes: Interlocked.Read(ref _totalTransferredBytes),
totalBytes: _contentLength
);

_fileTransporterRequest.OnRaiseTransferCompletedEvent(completedArgs);
}

private void FireTransferFailedEvent()
{
var failedArgs = new UploadFailedEventArgs(
request: _fileTransporterRequest,
filePath: _fileTransporterRequest.FilePath,
transferredBytes: Interlocked.Read(ref _totalTransferredBytes),
totalBytes: _contentLength
);

_fileTransporterRequest.OnRaiseTransferFailedEvent(failedArgs);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,20 @@ await this.AsyncThrottler.WaitAsync(cancellationToken)
.ConfigureAwait(continueOnCapturedContext: false);
}

FireTransferInitiatedEvent();

var putRequest = ConstructRequest();
await _s3Client.PutObjectAsync(putRequest, cancellationToken)
var response = await _s3Client.PutObjectAsync(putRequest, cancellationToken)
.ConfigureAwait(continueOnCapturedContext: false);

var mappedResponse = ResponseMapper.MapPutObjectResponse(response);

FireTransferCompletedEvent(mappedResponse);
}
catch (Exception)
{
FireTransferFailedEvent();
throw;
}
finally
{
Expand Down
Loading