Skip to content

Expose the details of batch uploads and transfer the process of controlling progress to the caller. Support the use of streaming to upload empty files #1210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
79 changes: 0 additions & 79 deletions Minio/AWSS3Endpoints.cs

This file was deleted.

65 changes: 64 additions & 1 deletion Minio/ApiEndpoints/IObjectOperations.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage,
* (C) 2017-2021 MinIO, Inc.
*
Expand Down Expand Up @@ -358,4 +358,67 @@ IAsyncEnumerable<Upload> ListIncompleteUploadsEnumAsync(ListIncompleteUploadsArg
/// <exception cref="ObjectNotFoundException">When object is not found</exception>
/// <exception cref="MalFormedXMLException">When configuration XML provided is invalid</exception>
Task RemoveObjectTagsAsync(RemoveObjectTagsArgs args, CancellationToken cancellationToken = default);

/// <summary>
/// Upload object part to bucket for particular uploadId
/// </summary>
/// <param name="args">
/// PutObjectArgs encapsulates bucket name, object name, upload id, part number, object data(body),
/// Headers, SSE Headers
/// </param>
/// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
/// <param name="singleFile">
/// This boolean parameter differentiates single part file upload and
/// multi part file upload as this function is shared by both.
/// </param>
/// <returns></returns>
/// <exception cref="AuthorizationException">When access or secret key is invalid</exception>
/// <exception cref="InvalidBucketNameException">When bucket name is invalid</exception>
/// <exception cref="InvalidObjectNameException">When object name is invalid</exception>
/// <exception cref="BucketNotFoundException">When bucket is not found</exception>
/// <exception cref="ObjectDisposedException">The file stream has been disposed</exception>
/// <exception cref="NotSupportedException">The file stream cannot be read from</exception>
/// <exception cref="InvalidOperationException">The file stream is currently in a read operation</exception>
/// <exception cref="AccessDeniedException">For encrypted PUT operation, Access is denied if the key is wrong</exception>
Task<PutObjectResponse> PutObjectSinglePartAsync(PutObjectArgs args, CancellationToken cancellationToken = default, bool singleFile = false);


/// <summary>
/// Remove object with matching uploadId from bucket
/// </summary>
/// <param name="args">RemoveUploadArgs Arguments Object which encapsulates bucket, object names, upload Id</param>
/// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
/// <returns></returns>
Task RemoveUploadAsync(RemoveUploadArgs args, CancellationToken cancellationToken);

/// <summary>
/// Start a new multi-part upload request
/// </summary>
/// <param name="args">
/// NewMultipartUploadPutArgs arguments object encapsulating bucket name, object name, Headers, SSE
/// Headers
/// </param>
/// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
/// <returns></returns>
/// <exception cref="AuthorizationException">When access or secret key is invalid</exception>
/// <exception cref="InvalidBucketNameException">When bucket name is invalid</exception>
/// <exception cref="InvalidObjectNameException">When object name is invalid</exception>
/// <exception cref="BucketNotFoundException">When bucket is not found</exception>
/// <exception cref="ObjectNotFoundException">When object is not found</exception>
/// <exception cref="AccessDeniedException">For encrypted copy operation, Access is denied if the key is wrong</exception>
Task<string> NewMultipartUploadAsync(NewMultipartUploadPutArgs args, CancellationToken cancellationToken = default);

/// <summary>
/// Internal method to complete multi part upload of object to server.
/// </summary>
/// <param name="args">CompleteMultipartUploadArgs Arguments object with bucket name, object name, upload id, Etags</param>
/// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
/// <returns></returns>
/// <exception cref="AuthorizationException">When access or secret key is invalid</exception>
/// <exception cref="InvalidBucketNameException">When bucket name is invalid</exception>
/// <exception cref="InvalidObjectNameException">When object name is invalid</exception>
/// <exception cref="BucketNotFoundException">When bucket is not found</exception>
/// <exception cref="ObjectNotFoundException">When object is not found</exception>
/// <exception cref="AccessDeniedException">For encrypted copy operation, Access is denied if the key is wrong</exception>
Task<PutObjectResponse> CompleteMultipartUploadAsync(CompleteMultipartUploadArgs args, CancellationToken cancellationToken);
}
14 changes: 7 additions & 7 deletions Minio/ApiEndpoints/ObjectOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ public async Task<PutObjectResponse> PutObjectAsync(PutObjectArgs args,
.ConfigureAwait(false);
putObjectResponse.Size = args.ObjectSize;
return putObjectResponse;
}
}

/// <summary>
/// Copy a source object into a new destination object.
Expand Down Expand Up @@ -804,7 +804,7 @@ await this.ExecuteTaskAsync(ResponseErrorHandlers, requestMessageBuilder,
/// <param name="args">RemoveUploadArgs Arguments Object which encapsulates bucket, object names, upload Id</param>
/// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
/// <returns></returns>
private async Task RemoveUploadAsync(RemoveUploadArgs args, CancellationToken cancellationToken)
public async Task RemoveUploadAsync(RemoveUploadArgs args, CancellationToken cancellationToken)
{
args?.Validate();
var requestMessageBuilder = await this.CreateRequest(args).ConfigureAwait(false);
Expand Down Expand Up @@ -835,7 +835,7 @@ await this.ExecuteTaskAsync(ResponseErrorHandlers, requestMessageBuilder,
/// <exception cref="NotSupportedException">The file stream cannot be read from</exception>
/// <exception cref="InvalidOperationException">The file stream is currently in a read operation</exception>
/// <exception cref="AccessDeniedException">For encrypted PUT operation, Access is denied if the key is wrong</exception>
private async Task<PutObjectResponse> PutObjectSinglePartAsync(PutObjectArgs args,
public async Task<PutObjectResponse> PutObjectSinglePartAsync(PutObjectArgs args,
CancellationToken cancellationToken = default,
bool singleFile = false)
{
Expand Down Expand Up @@ -915,10 +915,10 @@ private async Task<IDictionary<int, string>> PutObjectPartAsync(PutObjectPartArg
{
PartNumber = partNumber, ETag = etag, Size = (long)expectedReadSize
};
etags[partNumber] = etag;
if (!dataToCopy.IsEmpty) progressReport.TotalBytesTransferred += dataToCopy.Length;
if (args.ObjectSize != -1) progressReport.Percentage = (int)(100 * partNumber / partCount);
args.Progress?.Report(progressReport);
etags[partNumber] = etag;
}

// This shouldn't happen where stream size is known.
Expand Down Expand Up @@ -1034,7 +1034,7 @@ private async Task MultipartCopyUploadAsync(MultipartCopyUploadArgs args,
/// <exception cref="BucketNotFoundException">When bucket is not found</exception>
/// <exception cref="ObjectNotFoundException">When object is not found</exception>
/// <exception cref="AccessDeniedException">For encrypted copy operation, Access is denied if the key is wrong</exception>
private async Task<string> NewMultipartUploadAsync(NewMultipartUploadPutArgs args,
public async Task<string> NewMultipartUploadAsync(NewMultipartUploadPutArgs args,
CancellationToken cancellationToken = default)
{
args?.Validate();
Expand Down Expand Up @@ -1062,7 +1062,7 @@ await this.ExecuteTaskAsync(ResponseErrorHandlers, requestMessageBuilder,
/// <exception cref="BucketNotFoundException">When bucket is not found</exception>
/// <exception cref="ObjectNotFoundException">When object is not found</exception>
/// <exception cref="AccessDeniedException">For encrypted copy operation, Access is denied if the key is wrong</exception>
private async Task<string> NewMultipartUploadAsync(NewMultipartUploadCopyArgs args,
public async Task<string> NewMultipartUploadAsync(NewMultipartUploadCopyArgs args,
CancellationToken cancellationToken = default)
{
args?.Validate();
Expand Down Expand Up @@ -1105,7 +1105,7 @@ await this.ExecuteTaskAsync(ResponseErrorHandlers, requestMessageBuilder,
/// <exception cref="BucketNotFoundException">When bucket is not found</exception>
/// <exception cref="ObjectNotFoundException">When object is not found</exception>
/// <exception cref="AccessDeniedException">For encrypted copy operation, Access is denied if the key is wrong</exception>
private async Task<PutObjectResponse> CompleteMultipartUploadAsync(CompleteMultipartUploadArgs args,
public async Task<PutObjectResponse> CompleteMultipartUploadAsync(CompleteMultipartUploadArgs args,
CancellationToken cancellationToken)
{
args?.Validate();
Expand Down
2 changes: 1 addition & 1 deletion Minio/Credentials/WebIdentityProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage,
* (C) 2021 MinIO, Inc.
*
Expand Down
8 changes: 4 additions & 4 deletions Minio/DataModel/Args/BucketArgs.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage, (C) 2020, 2021 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -25,9 +25,9 @@ public abstract class BucketArgs<T> : RequestArgs

public bool IsBucketCreationRequest { get; set; }

internal string BucketName { get; set; }
public string BucketName { get; set; }

internal IDictionary<string, string> Headers { get; set; } = new Dictionary<string, string>(StringComparer.Ordinal);
public IDictionary<string, string> Headers { get; set; } = new Dictionary<string, string>(StringComparer.Ordinal);

public T WithBucket(string bucket)
{
Expand All @@ -48,7 +48,7 @@ public virtual T WithHeaders(IDictionary<string, string> headers)
return (T)this;
}

internal virtual void Validate()
public virtual void Validate()
{
Utils.ValidateBucketName(BucketName);
}
Expand Down
12 changes: 6 additions & 6 deletions Minio/DataModel/Args/CompleteMultipartUploadArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

namespace Minio.DataModel.Args;

internal class CompleteMultipartUploadArgs : ObjectWriteArgs<CompleteMultipartUploadArgs>
public class CompleteMultipartUploadArgs : ObjectWriteArgs<CompleteMultipartUploadArgs>
{
internal CompleteMultipartUploadArgs()
public CompleteMultipartUploadArgs()
{
RequestMethod = HttpMethod.Post;
}
Expand All @@ -40,10 +40,10 @@ internal CompleteMultipartUploadArgs(MultipartCopyUploadArgs args)
.ToDictionary(item => item.Key, item => item.First().Value, StringComparer.Ordinal);
}

internal string UploadId { get; set; }
public string UploadId { get; set; }
internal Dictionary<int, string> ETags { get; set; }

internal override void Validate()
public override void Validate()
{
base.Validate();
if (string.IsNullOrWhiteSpace(UploadId))
Expand All @@ -52,13 +52,13 @@ internal override void Validate()
throw new InvalidOperationException(nameof(ETags) + " dictionary cannot be empty.");
}

internal CompleteMultipartUploadArgs WithUploadId(string uploadId)
public CompleteMultipartUploadArgs WithUploadId(string uploadId)
{
UploadId = uploadId;
return this;
}

internal CompleteMultipartUploadArgs WithETags(IDictionary<int, string> etags)
public CompleteMultipartUploadArgs WithETags(IDictionary<int, string> etags)
{
if (etags?.Count > 0) ETags = new Dictionary<int, string>(etags);
return this;
Expand Down
2 changes: 1 addition & 1 deletion Minio/DataModel/Args/CopyObjectArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public CopyObjectArgs()
internal DateTime RetentionUntilDate { get; set; }
internal bool ObjectLockSet { get; set; }

internal override void Validate()
public override void Validate()
{
Utils.ValidateBucketName(BucketName);
if (SourceObject is null)
Expand Down
2 changes: 1 addition & 1 deletion Minio/DataModel/Args/CopyObjectRequestArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public CopyObjectRequestArgs WithObjectLockRetentionDate(DateTime untilDate)
return this;
}

internal override void Validate()
public override void Validate()
{
Utils.ValidateBucketName(BucketName); //Object name can be same as that of source.
if (SourceObject is null) throw new InvalidOperationException(nameof(SourceObject) + " has not been assigned.");
Expand Down
4 changes: 2 additions & 2 deletions Minio/DataModel/Args/EncryptionArgs.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage, (C) 2021 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -21,7 +21,7 @@ namespace Minio.DataModel.Args;
public abstract class EncryptionArgs<T> : ObjectArgs<T>
where T : EncryptionArgs<T>
{
internal IServerSideEncryption SSE { get; set; }
public IServerSideEncryption SSE { get; set; }

public T WithServerSideEncryption(IServerSideEncryption sse)
{
Expand Down
2 changes: 1 addition & 1 deletion Minio/DataModel/Args/GetObjectArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public GetObjectArgs()
internal string FileName { get; private set; }
internal bool OffsetLengthSet { get; set; }

internal override void Validate()
public override void Validate()
{
base.Validate();
if (CallBack is null && string.IsNullOrEmpty(FileName))
Expand Down
2 changes: 1 addition & 1 deletion Minio/DataModel/Args/NewMultipartUploadArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

namespace Minio.DataModel.Args;

internal class NewMultipartUploadArgs<T> : ObjectWriteArgs<T>
public class NewMultipartUploadArgs<T> : ObjectWriteArgs<T>
where T : NewMultipartUploadArgs<T>
{
internal NewMultipartUploadArgs()
Expand Down
4 changes: 2 additions & 2 deletions Minio/DataModel/Args/NewMultipartUploadCopyArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@

namespace Minio.DataModel.Args;

internal class NewMultipartUploadCopyArgs : NewMultipartUploadArgs<NewMultipartUploadCopyArgs>
public class NewMultipartUploadCopyArgs : NewMultipartUploadArgs<NewMultipartUploadCopyArgs>
{
internal bool ReplaceMetadataDirective { get; set; }
internal bool ReplaceTagsDirective { get; set; }
internal string StorageClass { get; set; }
internal ObjectStat SourceObjectInfo { get; set; }
internal CopySourceObjectArgs SourceObject { get; set; }

internal override void Validate()
public override void Validate()
{
base.Validate();
if (SourceObjectInfo is null || SourceObject is null)
Expand Down
2 changes: 1 addition & 1 deletion Minio/DataModel/Args/NewMultipartUploadPutArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

namespace Minio.DataModel.Args;

internal class NewMultipartUploadPutArgs : NewMultipartUploadArgs<NewMultipartUploadPutArgs>
public class NewMultipartUploadPutArgs : NewMultipartUploadArgs<NewMultipartUploadPutArgs>
{
internal override HttpRequestMessageBuilder BuildRequest(HttpRequestMessageBuilder requestMessageBuilder)
{
Expand Down
8 changes: 4 additions & 4 deletions Minio/DataModel/Args/ObjectArgs.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage, (C) 2020 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -23,8 +23,8 @@ public abstract class ObjectArgs<T> : BucketArgs<T>
{
protected const string S3ZipExtractKey = "X-Minio-Extract";

internal string ObjectName { get; set; }
internal ReadOnlyMemory<byte> RequestBody { get; set; }
public string ObjectName { get; set; }
public ReadOnlyMemory<byte> RequestBody { get; set; }

public T WithObject(string obj)
{
Expand All @@ -38,7 +38,7 @@ public T WithRequestBody(ReadOnlyMemory<byte> data)
return (T)this;
}

internal override void Validate()
public override void Validate()
{
base.Validate();
Utils.ValidateObjectName(ObjectName);
Expand Down
Loading