diff --git a/.gitignore b/.gitignore index f1b2c380..d0a97171 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ Backup* bin -obj \ No newline at end of file +obj +/.vs diff --git a/sdk/Commands/OssCommand.cs b/sdk/Commands/OssCommand.cs index aac1503e..4eafb430 100644 --- a/sdk/Commands/OssCommand.cs +++ b/sdk/Commands/OssCommand.cs @@ -11,6 +11,9 @@ using Aliyun.OSS.Common.Communication; using Aliyun.OSS.Util; using Aliyun.OSS.Transform; +using System.Threading.Tasks; +using System.Threading; +using ExecutionContext = Aliyun.OSS.Common.Communication.ExecutionContext; namespace Aliyun.OSS.Commands { @@ -96,6 +99,20 @@ public ServiceResponse Execute() } } + public async Task ExecuteAsync(CancellationToken cancellationToken=default) + { + var request = BuildRequest(); + try + { + return await Client.SendAsync(request, Context, cancellationToken); + } + finally + { + if (!LeaveRequestOpen) + request.Dispose(); + } + } + public IAsyncResult AsyncExecute(AsyncCallback callback, Object state) { var request = BuildRequest(); @@ -161,6 +178,12 @@ protected OssCommand(IServiceClient client, Uri endpoint, ExecutionContext conte return DeserializeResponse(response); } + public new async Task ExecuteAsync(CancellationToken cancellationToken= default) + { + var response = await base.ExecuteAsync(cancellationToken); + return DeserializeResponse(response); + } + public T DeserializeResponse(ServiceResponse response) { try diff --git a/sdk/Common/Communication/IServiceClient.cs b/sdk/Common/Communication/IServiceClient.cs index 1b5b7c37..6bb19c80 100644 --- a/sdk/Common/Communication/IServiceClient.cs +++ b/sdk/Common/Communication/IServiceClient.cs @@ -5,6 +5,8 @@ */ using System; +using System.Threading; +using System.Threading.Tasks; namespace Aliyun.OSS.Common.Communication { @@ -37,5 +39,14 @@ internal interface IServiceClient /// An instance of . /// The response data. ServiceResponse EndSend(IAsyncResult asyncResult); + + /// + /// Sends a request to the service. + /// + /// + /// + /// + /// + Task SendAsync(ServiceRequest request, ExecutionContext context, CancellationToken cancellationToken=default); } } diff --git a/sdk/Common/Communication/RetryableServiceClient.cs b/sdk/Common/Communication/RetryableServiceClient.cs index 101cd220..e461782f 100644 --- a/sdk/Common/Communication/RetryableServiceClient.cs +++ b/sdk/Common/Communication/RetryableServiceClient.cs @@ -9,6 +9,7 @@ using System.Threading; using System.IO; using Aliyun.OSS.Util; +using System.Threading.Tasks; namespace Aliyun.OSS.Common.Communication { @@ -79,6 +80,32 @@ private ServiceResponse SendImpl(ServiceRequest request, ExecutionContext contex } } + private async Task SendImplAsync(ServiceRequest request, ExecutionContext context, int retryTimes, CancellationToken cancellationToken = default) + { + long originalContentPosition = -1; + try + { + if (request.Content != null && request.Content.CanSeek) + originalContentPosition = request.Content.Position; + return await _innerClient.SendAsync(request, context, cancellationToken); + } + catch (Exception ex) + { + if (ShouldRetry(request, ex, retryTimes)) + { + if (request.Content != null && (originalContentPosition >= 0 && request.Content.CanSeek)) + request.Content.Seek(originalContentPosition, SeekOrigin.Begin); + + Pause(retryTimes); + + return await SendImplAsync(request, context, ++retryTimes, cancellationToken); + } + + // Rethrow + throw; + } + } + public IAsyncResult BeginSend(ServiceRequest request, ExecutionContext context, AsyncCallback callback, object state) { @@ -166,6 +193,11 @@ private static void Pause(int retryTimes) Thread.Sleep(delay); } + public async Task SendAsync(ServiceRequest request, ExecutionContext context, CancellationToken cancellationToken = default) + { + return await SendImplAsync(request, context, 0, cancellationToken); + } + #endregion } diff --git a/sdk/Common/Communication/ServiceClient.cs b/sdk/Common/Communication/ServiceClient.cs index 55c34646..0222234c 100644 --- a/sdk/Common/Communication/ServiceClient.cs +++ b/sdk/Common/Communication/ServiceClient.cs @@ -10,6 +10,8 @@ using Aliyun.OSS.Util; using Aliyun.OSS.Common.Handlers; using Aliyun.OSS.Properties; +using System.Threading.Tasks; +using System.Threading; namespace Aliyun.OSS.Common.Communication { @@ -56,7 +58,7 @@ public static ServiceClient Create(ClientConfiguration configuration) #endregion -#region IServiceClient Members + #region IServiceClient Members public ServiceResponse Send(ServiceRequest request, ExecutionContext context) { @@ -96,10 +98,11 @@ public ServiceResponse EndSend(IAsyncResult aysncResult) } } -#endregion + #endregion protected abstract ServiceResponse SendCore(ServiceRequest request, ExecutionContext context); - + protected abstract Task SendCoreAsync(ServiceRequest request, ExecutionContext context, CancellationToken cancellationToken=default); + protected abstract IAsyncResult BeginSendCore(ServiceRequest request, ExecutionContext context, AsyncCallback callback, Object state); @@ -114,5 +117,13 @@ protected static void HandleResponse(ServiceResponse response, IEnumerable SendAsync(ServiceRequest request, ExecutionContext context, System.Threading.CancellationToken cancellationToken = default) + { + SignRequest(request, context); + var response = await SendCoreAsync(request, context); + HandleResponse(response, context.ResponseHandlers); + return response; + } } } diff --git a/sdk/Common/Communication/ServiceClientImpl.cs b/sdk/Common/Communication/ServiceClientImpl.cs index fc8f8470..f35159c0 100644 --- a/sdk/Common/Communication/ServiceClientImpl.cs +++ b/sdk/Common/Communication/ServiceClientImpl.cs @@ -15,6 +15,7 @@ using System.Net.Security; using Aliyun.OSS.Util; +using System.Threading.Tasks; namespace Aliyun.OSS.Common.Communication { @@ -363,6 +364,69 @@ private static ServiceResponse HandleException(WebException ex) return new ResponseImpl(ex); } + protected override async Task SendCoreAsync(ServiceRequest serviceRequest, ExecutionContext context, System.Threading.CancellationToken cancellationToken = default) + { + var request = HttpFactory.CreateWebRequest(serviceRequest, Configuration); + await SetRequestContentAsync(request, serviceRequest, Configuration); + try + { + var response = (await request.GetResponseAsync()) as HttpWebResponse; + return new ResponseImpl(response); + } + catch (WebException ex) + { + return HandleException(ex); + } + } + + + private static async Task SetRequestContentAsync(HttpWebRequest webRequest, + ServiceRequest serviceRequest, + ClientConfiguration clientConfiguration) + { + var data = serviceRequest.BuildRequestContent(); + + if (data == null || + (serviceRequest.Method != HttpMethod.Put && + serviceRequest.Method != HttpMethod.Post)) + { + return; + } + + // Write data to the request stream. + long userSetContentLength = -1; + if (serviceRequest.Headers.ContainsKey(HttpHeaders.ContentLength)) + userSetContentLength = long.Parse(serviceRequest.Headers[HttpHeaders.ContentLength]); + + if (serviceRequest.UseChunkedEncoding || !data.CanSeek) // when data cannot seek, we have to use chunked encoding as there's no way to set the length + { + webRequest.SendChunked = true; + webRequest.AllowWriteStreamBuffering = false; // when using chunked encoding, the data is likely big and thus not use write buffer; + } + else + { + long streamLength = data.Length - data.Position; + webRequest.ContentLength = (userSetContentLength >= 0 && + userSetContentLength <= streamLength) ? userSetContentLength : streamLength; + if (webRequest.ContentLength > clientConfiguration.DirectWriteStreamThreshold) + { + webRequest.AllowWriteStreamBuffering = false; + } + } + + using (var requestStream = webRequest.GetRequestStream()) + { + if (!webRequest.SendChunked) + { + await IoUtils.WriteToAsync(data, requestStream, webRequest.ContentLength); + } + else + { + await IoUtils.WriteToAsync(data, requestStream); + } + } + } + #endregion } diff --git a/sdk/Common/Communication/netcore/ServiceClientNewImpl.cs b/sdk/Common/Communication/netcore/ServiceClientNewImpl.cs index e25e4a90..ba0a5c86 100644 --- a/sdk/Common/Communication/netcore/ServiceClientNewImpl.cs +++ b/sdk/Common/Communication/netcore/ServiceClientNewImpl.cs @@ -370,8 +370,18 @@ private bool CanReuseHttpClient(ClientConfiguration dst, ClientConfiguration src return true; } return false; - } - + } + + protected override async Task SendCoreAsync(ServiceRequest request, ExecutionContext context, System.Threading.CancellationToken cancellationToken = default) + { + var req = new HttpRequestMessage(Convert(request.Method), request.BuildRequestUri()); + this.SetRequestContent(req, request); + this.SetHeaders(req, request); + HttpClient client = GetClient(); + HttpResponseMessage resp = await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead); + return new ResponseImpl(resp); + } + private static HttpClient _httpClient; private static HttpClient _httpClientNoProxy; private static object _clientLock = new object(); diff --git a/sdk/Common/ResumableDownloadManager.cs b/sdk/Common/ResumableDownloadManager.cs index eba184ec..77bf2561 100644 --- a/sdk/Common/ResumableDownloadManager.cs +++ b/sdk/Common/ResumableDownloadManager.cs @@ -16,6 +16,7 @@ using Aliyun.OSS.Util; using Aliyun.OSS.Common; using Aliyun.OSS.Common.Internal; +using System.Threading.Tasks; namespace Aliyun.OSS { @@ -158,6 +159,21 @@ internal static long WriteTo(Stream src, Stream dest) return totalBytes; } + internal static async Task WriteToAsync(Stream src, Stream dest, CancellationToken cancellation) + { + var buffer = new byte[32 * 1024]; + var bytesRead = 0; + var totalBytes = 0; + while ((bytesRead = await src.ReadAsync(buffer, 0, buffer.Length, cancellation)) > 0) + { + await dest.WriteAsync(buffer, 0, bytesRead, cancellation); + totalBytes += bytesRead; + } + await dest.FlushAsync(); + + return totalBytes; + } + internal class DownloadTaskParam { public DownloadObjectRequest Request diff --git a/sdk/IOss.Async.cs b/sdk/IOss.Async.cs new file mode 100644 index 00000000..b2aecca0 --- /dev/null +++ b/sdk/IOss.Async.cs @@ -0,0 +1,921 @@ +using Aliyun.OSS.Model; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Aliyun.OSS +{ + public partial interface IOss + { + #region Bucket Operations + + /// + /// Creates a new bucket + /// + /// The bucket name. It must be globably unique. + /// instance + Task CreateBucketAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Creates the bucket with specified storage class. + /// + /// The bucket. + /// Bucket name. + /// Storage class. + Task CreateBucketAsync(string bucketName, StorageClass? storageClass, CancellationToken cancellation = default); + + /// + /// Creates a bucket + /// + /// The bucket. + /// + Task CreateBucketAsync(CreateBucketRequest createBucketRequest, CancellationToken cancellation = default); + + /// + /// Deletes a empty bucket.If the bucket is not empty, this will fail. + /// + /// The bucket name to delete + Task DeleteBucketAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// List all buckets under the current account. + /// + /// All instances + Task> ListBucketsAsync(CancellationToken cancellation = default); + + /// + /// Lists all buckets according to the ListBucketsRequest, which could have filters by prefix, marker, etc. + /// + /// instance + /// instance + Task ListBucketsAsync(ListBucketsRequest listBucketsRequest, CancellationToken cancellation = default); + + /// + /// Gets the bucket information. + /// + /// The bucket information. + /// Bucket name. + Task GetBucketInfoAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Gets the bucket stat. + /// + /// The bucket stat. + /// Bucket name. + Task GetBucketStatAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets the bucket ACL + /// + /// name + /// instance + Task SetBucketAclAsync(string bucketName, CannedAccessControlList acl, CancellationToken cancellation = default); + + /// + /// Sets the bucket ACL + /// + /// + Task SetBucketAclAsync(SetBucketAclRequest setBucketAclRequest, CancellationToken cancellation = default); + + /// + /// Gets the bucket ACL + /// + /// name + /// Bucket ACL instance + Task GetBucketAclAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Gets the bucket location + /// + /// bucket name + /// bucket location + Task GetBucketLocationAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Gets the bucket metadata + /// + /// bucket name + /// metadata + Task GetBucketMetadataAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets the CORS rules for the + /// + /// + Task SetBucketCorsAsync(SetBucketCorsRequest setBucketCorsRequest, CancellationToken cancellation = default); + + /// + /// Gets the CORS rules. + /// + /// bucket name + /// CORS rules + Task> GetBucketCorsAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Deletes the CORS rules on the + /// + /// name + Task DeleteBucketCorsAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets logging config + /// OSS will log the access information on this bucket, according to the logging config + /// The hourly log file will be stored in the target bucket. + /// + /// + Task SetBucketLoggingAsync(SetBucketLoggingRequest setBucketLoggingRequest, CancellationToken cancellation = default); + + /// + /// Gets the bucket logging config + /// + /// name + /// The logging config result + Task GetBucketLoggingAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Deletes the logging config + /// + /// name + Task DeleteBucketLoggingAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets static website config + /// + /// instance + Task SetBucketWebsiteAsync(SetBucketWebsiteRequest setBucketWebSiteRequest, CancellationToken cancellation = default); + + + /// + /// Gets static website config + /// + /// name + /// instance + Task GetBucketWebsiteAsync(string bucketName, CancellationToken cancellation = default); + + + /// + /// Deletes the static website config + /// + /// 的名称。 + Task DeleteBucketWebsiteAsync(string bucketName, CancellationToken cancellation = default); + + + /// + /// Sets the referer config + /// + /// The requests that contains the Referer whitelist + Task SetBucketRefererAsync(SetBucketRefererRequest setBucketRefererRequest, CancellationToken cancellation = default); + + /// + /// Gets the referer config + /// + /// name + /// Referer config + Task GetBucketRefererAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets lifecycle rule + /// + /// the instance + Task SetBucketLifecycleAsync(SetBucketLifecycleRequest setBucketLifecycleRequest, CancellationToken cancellation = default); + + /// + /// Deletes the bucket's all lifecycle rules. + /// + /// Bucket name. + Task DeleteBucketLifecycleAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Gets lifecycle instance. + /// + /// bucket name + /// Lifecycle list + Task> GetBucketLifecycleAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets storage capacity + /// + /// instance + Task SetBucketStorageCapacityAsync(SetBucketStorageCapacityRequest setBucketStorageCapacityRequest, CancellationToken cancellation = default); + + /// + /// Gets storage capacity + /// + /// name + /// instance + Task GetBucketStorageCapacityAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Checks if the bucket exists + /// + /// name + /// + /// True when the bucket exists under the current user; + /// Otherwise returns false. + /// + Task DoesBucketExistAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets policy + /// + /// instance + Task SetBucketPolicyAsync(SetBucketPolicyRequest setBucketPolicyRequest, CancellationToken cancellation = default); + + /// + /// Gets policy + /// + /// name + /// instance + Task GetBucketPolicyAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Deletes policy. + /// + /// Bucket name. + Task DeleteBucketPolicyAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets bucket tagging + /// + /// instance + Task SetBucketTaggingAsync(SetBucketTaggingRequest setBucketTaggingRequest, CancellationToken cancellation = default); + + /// + /// Deletes the bucket's tagging. + /// + /// Bucket name. + Task DeleteBucketTaggingAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Deletes the bucket's tagging. + /// + /// DeleteBucketTaggingRequest. + Task DeleteBucketTaggingAsync(DeleteBucketTaggingRequest deleteBucketTaggingRequest, CancellationToken cancellation = default); + + /// + /// Gets bucket tagging + /// + /// name + /// instance + Task GetBucketTaggingAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets bucket request payment + /// + /// instance + Task SetBucketRequestPaymentAsync(SetBucketRequestPaymentRequest setBucketRequestPaymentRequest, CancellationToken cancellation = default); + + /// + /// Gets bucket request payment + /// + /// name + /// + Task GetBucketRequestPaymentAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets bucket encryption rule + /// + /// instance + Task SetBucketEncryptionAsync(SetBucketEncryptionRequest setBucketEncryptionRequest, CancellationToken cancellation = default); + + /// + /// Deletes bucket encryption rule + /// + /// Bucket name. + Task DeleteBucketEncryptionAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Gets bucket encryption rule + /// + /// name + /// instance + Task GetBucketEncryptionAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets bucket versioning + /// + /// instance + Task SetBucketVersioningAsync(SetBucketVersioningRequest setBucketVersioningRequest, CancellationToken cancellation = default); + + /// + /// Gets bucket versioning + /// + /// name + /// instance + Task GetBucketVersioningAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// Sets bucket inventory configuration + /// + /// instance + Task SetBucketInventoryConfigurationAsync(SetBucketInventoryConfigurationRequest request, CancellationToken cancellation = default); + + /// + /// Deletes bucket inventory configuration + /// + /// instance + Task DeleteBucketInventoryConfigurationAsync(DeleteBucketInventoryConfigurationRequest request, CancellationToken cancellation = default); + + /// + /// Gets bucket inventory configuration + /// + /// instance + /// instance + Task GetBucketInventoryConfigurationAsync(GetBucketInventoryConfigurationRequest request, CancellationToken cancellation = default); + + /// + /// Gets bucket inventory configuration + /// + /// instance + /// instance + Task ListBucketInventoryConfigurationAsync(ListBucketInventoryConfigurationRequest request, CancellationToken cancellation = default); + + /// + /// InitiateBucketWorm + /// + /// instance + /// instance + Task InitiateBucketWormAsync(InitiateBucketWormRequest request, CancellationToken cancellation = default); + + /// + /// Gets AbortBucketWorm + /// + /// Bucket name. + Task AbortBucketWormAsync(string bucketName, CancellationToken cancellation = default); + + /// + /// CompleteBucketWorm + /// + /// instance + Task CompleteBucketWormAsync(CompleteBucketWormRequest request, CancellationToken cancellation = default); + + /// + /// ExtendBucketWorm + /// + /// instance + Task ExtendBucketWormAsync(ExtendBucketWormRequest request, CancellationToken cancellation = default); + + /// + /// GetBucketWormResult + /// + /// Bucket name. + /// instance + Task GetBucketWormAsync(string bucketName, CancellationToken cancellation = default); + #endregion + + #region Object Operations + + /// + /// Lists all objects under the + /// + /// name + /// list + Task ListObjectsAsync(string bucketName, CancellationToken cancellation = default); + + + /// + /// Lists object with specified prefix + /// + /// name + /// prefix + /// instances list + Task ListObjectsAsync(string bucketName, string prefix, CancellationToken cancellation = default); + + + /// + /// Lists objects according to the ListObjectsRequest. + /// The returned object is type of OssObjectSummary. + /// + /// instance + /// list + Task ListObjectsAsync(ListObjectsRequest listObjectsRequest, CancellationToken cancellation = default); + + + /// + /// Lists object vesions according to the ListObjectVersionsRequest. + /// The returned object is type of OssObjectSummary. + /// + /// instance + /// list + Task ListObjectVersionsAsync(ListObjectVersionsRequest listObjectVersionsRequest, CancellationToken cancellation = default); + + /// + /// Puts object to the specified bucket with specified object key. + /// + /// specified bucket name + /// + /// + /// instance + Task PutObjectAsync(string bucketName, string key, Stream content, CancellationToken cancellation = default); + + + /// + /// Uploads the content to object under the specified bucket and object key. + /// + /// name + /// + /// + /// metadata + /// instance + Task PutObjectAsync(string bucketName, string key, Stream content, ObjectMetadata metadata, CancellationToken cancellation = default); + + /// + /// Upload a according to . + /// + /// instance + /// instance + Task PutObjectAsync(PutObjectRequest putObjectRequest, CancellationToken cancellation = default); + + + /// + /// Uploads a local file to OSS under the specified bucket + /// + /// name + /// + /// local file path to upload + /// instance + Task PutObjectAsync(string bucketName, string key, string fileToUpload, CancellationToken cancellation = default); + + /// + /// Uploads a local file with specified metadata to OSS. + /// + /// name + /// + /// local file path + /// metadata + /// instance + Task PutObjectAsync(string bucketName, string key, string fileToUpload, ObjectMetadata metadata, CancellationToken cancellation = default); + + + + /// + /// Uploads the file via the signed url. + /// + /// Signed url + /// File to upload + /// instance + Task PutObjectAsync(Uri signedUrl, string fileToUpload, CancellationToken cancellation = default); + + /// + /// Uploads the instream via the signed url. + /// + /// Signed url + /// content stream + /// instance + Task PutObjectAsync(Uri signedUrl, Stream content, CancellationToken cancellation = default); + + /// + /// Uploads the file via the signed url with the metadata. + /// + /// The signed url + /// Local file path + /// instance + /// metadata + Task PutObjectAsync(Uri signedUrl, string fileToUpload, ObjectMetadata metadata, CancellationToken cancellation = default); + + /// + /// Uploads the stream via the signed url with the metadata. + /// + /// Signed url + /// content stream + /// instance + /// metadata + Task PutObjectAsync(Uri signedUrl, Stream content, ObjectMetadata metadata, CancellationToken cancellation = default); + + + /// + /// Deprecated. Use ResumableCopyObject instead. + /// Copy the specified file with optional checkpoint support. + /// + /// the request parameter + /// part size. If the part size is not specified, or less than , + /// will be used instead. + /// + /// The checkpoint file folder. If it's not specified, checkpoint information is not stored and resumnable upload will not be supported in this case. + /// instance. + [Obsolete("CopyBigObject is deprecated, please use ResumableUploadObjectAsync instead")] + Task CopyBigObjectAsync(CopyObjectRequest copyObjectRequest, long? partSize = null, string checkpointDir = null, CancellationToken cancellation = default); + + /// + /// Resumable file upload. It automaticlly uses multipart upload upon big file and also support resume upload after a failed upload. + /// + /// instance + /// instance + /// file to upload + /// metadata + /// Check point dir. If it's not specified, then no checkpoint file is saved and thus resumable file upload is not supported. + /// Part size. If it's not specified, or the size is smaller than + /// then is used instead. + /// + /// instance + Task ResumableUploadObjectAsync(string bucketName, string key, string fileToUpload, ObjectMetadata metadata, string checkpointDir, long? partSize = null, + EventHandler streamTransferProgress = null, CancellationToken cancellation = default); + + /// + /// Resumable file upload. It automaticlly uses multipart upload upon big file and also support resume upload after a failed upload. + /// + /// name + /// + /// . Content is disposed after the call finishes. + /// metadata + /// Check point dir. If it's not specified, then no checkpoint file is saved and thus resumable file upload is not supported. + /// Part size. If it's not specified, or the size is smaller than + /// then is used instead. + /// + /// instance + Task ResumableUploadObjectAsync(string bucketName, string key, Stream content, ObjectMetadata metadata, string checkpointDir, long? partSize = null, + EventHandler streamTransferProgress = null, CancellationToken cancellation = default); + + /// + /// Resumables the upload object. + /// The request.UploadStream will be disposed once the call finishes. + /// + /// The upload object. + /// Upload Request. + Task ResumableUploadObjectAsync(UploadObjectRequest request, CancellationToken cancellation = default); + + /// + /// Appends object to OSS according to the + /// + /// instance + /// result + Task AppendObjectAsync(AppendObjectRequest request, CancellationToken cancellation = default); + + + /// + /// Creates the symlink of the target object + /// + /// Bucket name. + /// Symlink. + /// Target. + /// instance + Task CreateSymlinkAsync(string bucketName, string symlink, string target, CancellationToken cancellation = default); + + /// + /// Creates the symlink of the target object + /// + /// Create symlink request. + /// instance + Task CreateSymlinkAsync(CreateSymlinkRequest createSymlinkRequest, CancellationToken cancellation = default); + + /// + /// Gets the target file of the symlink. + /// + /// Bucket name. + /// Symlink + /// OssSymlink object + Task GetSymlinkAsync(string bucketName, string symlink, CancellationToken cancellation = default); + + /// + /// Gets the target file of the symlink. + /// + /// Get symlink request. + /// OssSymlink object + Task GetSymlinkAsync(GetSymlinkRequest getSymlinkRequest, CancellationToken cancellation = default); + + /// + /// Gets object + /// + /// bucket name + /// + /// instance + Task GetObjectAsync(string bucketName, string key, CancellationToken cancellation = default); + + /// + /// Gets object via signed url + /// + /// The signed url of HTTP GET method + /// instance + Task GetObjectAsync(Uri signedUrl, CancellationToken cancellation = default); + + /// + /// Gets object via the bucket name and key name in the instance. + /// + /// The request parameter + /// instance. The caller needs to dispose the object. + Task GetObjectAsync(GetObjectRequest getObjectRequest, CancellationToken cancellation = default); + + + /// + /// Gets the object and assign the data to the stream. + /// + /// request parameter + /// output stream + /// metadata + Task GetObjectAsync(GetObjectRequest getObjectRequest, Stream output, CancellationToken cancellation = default); + + /// + /// Download a file. + /// Internally it may use multipart download in case the file is big + /// + /// The metadata object + /// DownloadObjectRequest instance + Task ResumableDownloadObjectAsync(DownloadObjectRequest request, CancellationToken cancellation = default); + + /// + /// Gets metadata. + /// + /// name + /// + /// metadata + Task GetObjectMetadataAsync(string bucketName, string key, CancellationToken cancellation = default); + + /// + /// Gets metadata. + /// + /// GetObjectMetadataRequest instance + /// metadata + Task GetObjectMetadataAsync(GetObjectMetadataRequest request, CancellationToken cancellation = default); + + /// + /// Gets metadata. + /// + /// GetObjectMetadataRequest instance + /// metadata + Task GetSimplifiedObjectMetadataAsync(GetObjectMetadataRequest request, CancellationToken cancellation = default); + + /// + /// Deletes + /// + /// name + /// + /// instance + Task DeleteObjectAsync(string bucketName, string key, CancellationToken cancellation = default); + + /// + /// Deletes + /// + /// the request parameter + /// instance + Task DeleteObjectAsync(DeleteObjectRequest deleteObjectRequest, CancellationToken cancellation = default); + + /// + /// Deletes multiple objects + /// + /// the request parameter + /// delete object result + Task DeleteObjectsAsync(DeleteObjectsRequest deleteObjectsRequest, CancellationToken cancellation = default); + + /// + /// Deletes multiple objects with version id + /// + /// the request parameter + /// delete object result + Task DeleteObjectVersionsAsync(DeleteObjectVersionsRequest deleteObjectVersionsRequest, CancellationToken cancellation = default); + + /// + /// copy an object to another one in OSS. + /// + /// The request parameter + /// copy object result + Task CopyObjectAsync(CopyObjectRequest copyObjectRequst, CancellationToken cancellation = default); + + + /// + /// Resumable object copy. + /// If the file size is less than part size, normal file upload is used; otherwise multipart upload is used. + /// + /// request parameter + /// checkpoint file folder + /// The part size. + /// + /// instance + Task ResumableCopyObjectAsync(CopyObjectRequest copyObjectRequest, string checkpointDir, long? partSize = null, CancellationToken cancellation = default); + + /// + /// Modify the object metadata. + /// + /// name + /// + /// new metadata + /// check point folder. It must be specified to store the checkpoint information + /// Part size, it's no less than + /// + Task ModifyObjectMetaAsync(string bucketName, string key, ObjectMetadata newMeta, long? partSize = null, string checkpointDir = null, CancellationToken cancellation = default); + + /// + /// Checks if the object exists + /// + /// name + /// + /// true:object exists;false:otherwise + Task DoesObjectExistAsync(string bucketName, string key, CancellationToken cancellation = default); + + /// + /// Sets the object ACL + /// + /// name + /// key + /// instance + Task SetObjectAclAsync(string bucketName, string key, CannedAccessControlList acl, CancellationToken cancellation = default); + + /// + /// Sets the object ACL + /// + /// + Task SetObjectAclAsync(SetObjectAclRequest setObjectAclRequest, CancellationToken cancellation = default); + + /// + /// Gets the object ACL + /// + /// name + /// + /// instance + Task GetObjectAclAsync(string bucketName, string key, CancellationToken cancellation = default); + + /// + /// Gets the object ACL + /// + /// + Task GetObjectAclAsync(GetObjectAclRequest getObjectAclRequest, CancellationToken cancellation = default); + + /// + /// Restores the object. + /// + /// The object. + /// Bucket name. + /// Key. + Task RestoreObjectAsync(string bucketName, string key, CancellationToken cancellation = default); + + /// + /// Restores the object. + /// + /// The object. + /// + Task RestoreObjectAsync(RestoreObjectRequest restoreObjectRequest, CancellationToken cancellation = default); + + /// + /// Sets the object tagging + /// + /// instance + Task SetObjectTaggingAsync(SetObjectTaggingRequest request, CancellationToken cancellation = default); + + /// + /// Gets the object tagging + /// + /// name + /// + /// instance + Task GetObjectTaggingAsync(string bucketName, string key, CancellationToken cancellation = default); + + /// + /// Gets the object tagging + /// + /// instance + /// instance + Task GetObjectTaggingAsync(GetObjectTaggingRequest request, CancellationToken cancellation = default); + + /// + /// Deletes object tagging + /// + /// name + /// + Task DeleteObjectTaggingAsync(string bucketName, string key, CancellationToken cancellation = default); + + /// + /// Deletes the object tagging + /// + /// instance + Task DeleteObjectTaggingAsync(DeleteObjectTaggingRequest request, CancellationToken cancellation = default); + + /// + /// Gets the contents of a object based on a SQL statement. + /// + /// instance + Task SelectObjectAsync(SelectObjectRequest request, CancellationToken cancellation = default); + + /// + /// Creates the meta of a select object + /// + /// instance + Task CreateSelectObjectMetaAsync(CreateSelectObjectMetaRequest request, CancellationToken cancellation = default); + + /// + /// Processes the object + /// + /// instance + /// instance + Task ProcessObjectAsync(ProcessObjectRequest request, CancellationToken cancellation = default); + + #endregion + + #region Multipart Operations + /// + /// Lists ongoing multipart uploads + /// + /// request parameter + /// instance + Task ListMultipartUploadsAsync(ListMultipartUploadsRequest listMultipartUploadsRequest, CancellationToken cancellation = default); + + /// + /// Initiate a multipart upload + /// + /// request parameter + /// instance + Task InitiateMultipartUploadAsync(InitiateMultipartUploadRequest initiateMultipartUploadRequest, CancellationToken cancellation = default); + + /// + /// Aborts a multipart upload + /// + /// request parameter + Task AbortMultipartUploadAsync(AbortMultipartUploadRequest abortMultipartUploadRequest, CancellationToken cancellation = default); + + /// + /// Uploads a part + /// + /// request parameter + /// instance + Task UploadPartAsync(UploadPartRequest uploadPartRequest, CancellationToken cancellation = default); + + /// + /// Copy an existing object as one part of a multipart upload. + /// + /// request parameter + /// instance + Task UploadPartCopyAsync(UploadPartCopyRequest uploadPartCopyRequest, CancellationToken cancellation = default); + + + /// + /// Lists successfully uploaded parts of a specific upload id + /// + /// request parameter + /// instance + Task ListPartsAsync(ListPartsRequest listPartsRequest, CancellationToken cancellation = default); + + /// + /// Completes a multipart upload. + /// + /// the request parameter + /// instance + Task CompleteMultipartUploadAsync(CompleteMultipartUploadRequest completeMultipartUploadRequest, CancellationToken cancellation = default); + + #endregion + + #region Live Channel + /// + /// Creates a live channel + /// + /// instance + /// instance + Task CreateLiveChannelAsync(CreateLiveChannelRequest request, CancellationToken cancellation = default); + + /// + /// Lists live channels + /// + /// instance + /// instance + Task ListLiveChannelAsync(ListLiveChannelRequest request, CancellationToken cancellation = default); + + /// + /// Deletes a live channel + /// + /// instance + Task DeleteLiveChannelAsync(DeleteLiveChannelRequest request, CancellationToken cancellation = default); + + /// + /// Sets the live channel status + /// + /// instance + Task SetLiveChannelStatusAsync(SetLiveChannelStatusRequest request, CancellationToken cancellation = default); + + /// + /// Gets the live channel information + /// + /// instance + /// instance + Task GetLiveChannelInfoAsync(GetLiveChannelInfoRequest request, CancellationToken cancellation = default); + + /// + /// Gets the live channel status + /// + /// instance + /// instance + Task GetLiveChannelStatAsync(GetLiveChannelStatRequest request, CancellationToken cancellation = default); + + /// + /// Gets the live channel history + /// + /// instance + /// instance + Task GetLiveChannelHistoryAsync(GetLiveChannelHistoryRequest request, CancellationToken cancellation = default); + + /// + /// Creates a vod playlist + /// + /// instance + Task PostVodPlaylistAsync(PostVodPlaylistRequest request, CancellationToken cancellation = default); + + /// + /// Gets a vod playlist + /// + /// instance + /// instance + Task GetVodPlaylistAsync(GetVodPlaylistRequest request, CancellationToken cancellation = default); + + #endregion + + } +} diff --git a/sdk/IOss.cs b/sdk/IOss.cs index 4be017a8..f612e5b5 100644 --- a/sdk/IOss.cs +++ b/sdk/IOss.cs @@ -27,7 +27,7 @@ namespace Aliyun.OSS /// OSS website:http://www.aliyun.com/product/oss /// /// - public interface IOss + public partial interface IOss { #region Switch Credentials & Endpoint diff --git a/sdk/OssClient.Async.cs b/sdk/OssClient.Async.cs new file mode 100644 index 00000000..c3ef67e6 --- /dev/null +++ b/sdk/OssClient.Async.cs @@ -0,0 +1,1583 @@ +using Aliyun.OSS.Commands; +using Aliyun.OSS.Common; +using Aliyun.OSS.Common.Authentication; +using Aliyun.OSS.Common.Communication; +using Aliyun.OSS.Common.Handlers; +using Aliyun.OSS.Common.Internal; +using Aliyun.OSS.Domain; +using Aliyun.OSS.Model; +using Aliyun.OSS.Properties; +using Aliyun.OSS.Transform; +using Aliyun.OSS.Util; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using ExecutionContext = Aliyun.OSS.Common.Communication.ExecutionContext; + +namespace Aliyun.OSS +{ + public partial class OssClient + { + #region Bucket Operations + /// + public async Task AbortBucketWormAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = AbortBucketWormCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, bucketName, null), + bucketName); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task CompleteBucketWormAsync(CompleteBucketWormRequest request, CancellationToken cancellation = default) + { + var cmd = CompleteBucketWormCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, request.BucketName, null), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task CreateBucketAsync(string bucketName, CancellationToken cancellation = default) + { + return await CreateBucketAsync(bucketName, null, cancellation); + } + + /// + public async Task CreateBucketAsync(string bucketName, StorageClass? storageClass, CancellationToken cancellation = default) + { + var cmd = CreateBucketCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, bucketName, null), + bucketName, storageClass); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + + return new Bucket(bucketName); + } + + /// + public async Task CreateBucketAsync(CreateBucketRequest createBucketRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(createBucketRequest); + + var cmd = CreateBucketCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, createBucketRequest.BucketName, null), + createBucketRequest.BucketName, createBucketRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + + return new Bucket(createBucketRequest.BucketName); + } + + /// + public async Task DeleteBucketAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = DeleteBucketCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, bucketName, null), + bucketName); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteBucketCorsAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = DeleteBucketCorsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, bucketName, null), + bucketName); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteBucketEncryptionAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = DeleteBucketEncryptionCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, bucketName, null), + bucketName); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteBucketInventoryConfigurationAsync(DeleteBucketInventoryConfigurationRequest request, CancellationToken cancellation = default) + { + var cmd = DeleteBucketInventoryConfigurationCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, request.BucketName, null), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteBucketLifecycleAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = DeleteBucketLifecycleCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, bucketName, null), + bucketName); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteBucketLoggingAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = DeleteBucketLoggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, bucketName, null), + bucketName); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteBucketPolicyAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = DeleteBucketPolicyCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, bucketName, null), + bucketName); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteBucketTaggingAsync(string bucketName, CancellationToken cancellation = default) + { + await DeleteBucketTaggingAsync(new DeleteBucketTaggingRequest(bucketName),cancellation); + } + + /// + public async Task DeleteBucketTaggingAsync(DeleteBucketTaggingRequest deleteBucketTaggingRequest, CancellationToken cancellation = default) + { + var cmd = DeleteBucketTaggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, deleteBucketTaggingRequest.BucketName, null), + deleteBucketTaggingRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteBucketWebsiteAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = DeleteBucketWebsiteCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, bucketName, null), + bucketName); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DoesBucketExistAsync(string bucketName, CancellationToken cancellation = default) + { + if (string.IsNullOrEmpty(bucketName)) + throw new ArgumentException(Resources.ExceptionIfArgumentStringIsNullOrEmpty, "bucketName"); + if (!OssUtils.IsBucketNameValid(bucketName)) + throw new ArgumentException(OssResources.BucketNameInvalid, "bucketName"); + + try + { + await GetBucketAclAsync(bucketName,cancellation); + } + catch (OssException e) + { + if (e.ErrorCode.Equals(OssErrorCode.NoSuchBucket)) + return false; + } + + return true; + } + + /// + public async Task ExtendBucketWormAsync(ExtendBucketWormRequest request, CancellationToken cancellation = default) + { + var cmd = ExtendBucketWormCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, request.BucketName, null), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task GetBucketAclAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketAclCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task> GetBucketCorsAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketCorsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketEncryptionAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketEncryptionCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketInfoAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketInfoCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketInventoryConfigurationAsync(GetBucketInventoryConfigurationRequest request, CancellationToken cancellation = default) + { + var cmd = GetBucketInventoryConfigurationCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, request.BucketName, null), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task> GetBucketLifecycleAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketLifecycleCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketLocationAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketLocationCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketLoggingAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketLoggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketMetadataAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketMetadataCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Head, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketPolicyAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketPolicyCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketRefererAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketRefererCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketRequestPaymentAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketRequestPaymentCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketStatAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketStatCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketStorageCapacityAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketStorageCapacityCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketTaggingAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketTaggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketVersioningAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketVersioningCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketWebsiteAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketWebsiteCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetBucketWormAsync(string bucketName, CancellationToken cancellation = default) + { + var cmd = GetBucketWormCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, bucketName, null), + bucketName); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task InitiateBucketWormAsync(InitiateBucketWormRequest request, CancellationToken cancellation = default) + { + var cmd = InitiateBucketWormCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, request.BucketName, null), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task ListBucketInventoryConfigurationAsync(ListBucketInventoryConfigurationRequest request, CancellationToken cancellation = default) + { + var cmd = ListBucketInventoryConfigurationCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, request.BucketName, null), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task> ListBucketsAsync(CancellationToken cancellation = default) + { + var cmd = ListBucketsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, null, null), null); + var result = await cmd.ExecuteAsync(cancellation); + return result.Buckets; + } + + /// + public async Task ListBucketsAsync(ListBucketsRequest listBucketsRequest, CancellationToken cancellation = default) + { + var cmd = ListBucketsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, null, null), listBucketsRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task SetBucketAclAsync(string bucketName, CannedAccessControlList acl, CancellationToken cancellation = default) + { + var setBucketAclRequest = new SetBucketAclRequest(bucketName, acl); + await SetBucketAclAsync(setBucketAclRequest, cancellation); + } + + /// + public async Task SetBucketAclAsync(SetBucketAclRequest setBucketAclRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketAclRequest); + + var cmd = SetBucketAclCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketAclRequest.BucketName, null), + setBucketAclRequest.BucketName, setBucketAclRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketCorsAsync(SetBucketCorsRequest setBucketCorsRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketCorsRequest); + var cmd = SetBucketCorsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketCorsRequest.BucketName, null), + setBucketCorsRequest.BucketName, + setBucketCorsRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketEncryptionAsync(SetBucketEncryptionRequest setBucketEncryptionRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketEncryptionRequest); + + var cmd = SetBucketEncryptionCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketEncryptionRequest.BucketName, null), + setBucketEncryptionRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketInventoryConfigurationAsync(SetBucketInventoryConfigurationRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = SetBucketInventoryConfigurationCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, request.BucketName, null), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketLifecycleAsync(SetBucketLifecycleRequest setBucketLifecycleRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketLifecycleRequest); + if (setBucketLifecycleRequest.LifecycleRules.Count == 0) + { + throw new ArgumentException("SetBucketLifecycleRequest must have at least one LifecycleRule."); + } + + var cmd = SetBucketLifecycleCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketLifecycleRequest.BucketName, null), + setBucketLifecycleRequest.BucketName, + setBucketLifecycleRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketLoggingAsync(SetBucketLoggingRequest setBucketLoggingRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketLoggingRequest); + var cmd = SetBucketLoggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketLoggingRequest.BucketName, null), + setBucketLoggingRequest.BucketName, + setBucketLoggingRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketPolicyAsync(SetBucketPolicyRequest setBucketPolicyRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketPolicyRequest); + + var cmd = SetBucketPolicyCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketPolicyRequest.BucketName, null), + setBucketPolicyRequest.BucketName, setBucketPolicyRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketRefererAsync(SetBucketRefererRequest setBucketRefererRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketRefererRequest); + var cmd = SetBucketRefererCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketRefererRequest.BucketName, null), + setBucketRefererRequest.BucketName, + setBucketRefererRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketRequestPaymentAsync(SetBucketRequestPaymentRequest setBucketRequestPaymentRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketRequestPaymentRequest); + + var cmd = SetBucketRequestPaymentCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketRequestPaymentRequest.BucketName, null), + setBucketRequestPaymentRequest.BucketName, + setBucketRequestPaymentRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketStorageCapacityAsync(SetBucketStorageCapacityRequest setBucketStorageCapacityRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketStorageCapacityRequest); + var cmd = SetBucketStorageCapacityCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketStorageCapacityRequest.BucketName, null), + setBucketStorageCapacityRequest.BucketName, + setBucketStorageCapacityRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketTaggingAsync(SetBucketTaggingRequest setBucketTaggingRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketTaggingRequest); + + var cmd = SetBucketTaggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketTaggingRequest.BucketName, null), + setBucketTaggingRequest.BucketName, + setBucketTaggingRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketVersioningAsync(SetBucketVersioningRequest setBucketVersioningRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketVersioningRequest); + + var cmd = SetBucketVersioningCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketVersioningRequest.BucketName, null), + setBucketVersioningRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetBucketWebsiteAsync(SetBucketWebsiteRequest setBucketWebSiteRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(setBucketWebSiteRequest); + var cmd = SetBucketWebsiteCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, setBucketWebSiteRequest.BucketName, null), + setBucketWebSiteRequest.BucketName, + setBucketWebSiteRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + #endregion + + #region Object Operations + /// + public async Task AppendObjectAsync(AppendObjectRequest request, CancellationToken cancellation) + { + ThrowIfNullRequest(request); + + var cmd = AppendObjectCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, request.BucketName, request.Key), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task CopyBigObjectAsync(CopyObjectRequest copyObjectRequest, long? partSize = null, string checkpointDir = null, CancellationToken cancellation = default) + { + return await ResumableCopyObjectAsync(copyObjectRequest, checkpointDir, partSize, cancellation); + } + + /// + public async Task CopyObjectAsync(CopyObjectRequest copyObjectRequst, CancellationToken cancellation) + { + ThrowIfNullRequest(copyObjectRequst); + var cmd = CopyObjectCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, copyObjectRequst.DestinationBucketName, copyObjectRequst.DestinationKey), + copyObjectRequst); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task CreateSelectObjectMetaAsync(CreateSelectObjectMetaRequest request, CancellationToken cancellation) + { + ThrowIfNullRequest(request); + + var cmd = CreateSelectObjectMetaCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, request.BucketName, request.Key), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task CreateSymlinkAsync(string bucketName, string symlink, string target, CancellationToken cancellation) + { + var cmd = CreateSymlinkCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, bucketName, symlink), + new CreateSymlinkRequest(bucketName, symlink, target)); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task CreateSymlinkAsync(CreateSymlinkRequest createSymlinkRequest, CancellationToken cancellation) + { + var cmd = CreateSymlinkCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, createSymlinkRequest.BucketName, createSymlinkRequest.Symlink), + createSymlinkRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task DeleteObjectAsync(string bucketName, string key, CancellationToken cancellation) + { + return await DeleteObjectAsync(new DeleteObjectRequest(bucketName, key), cancellation); + } + + /// + public async Task DeleteObjectAsync(DeleteObjectRequest deleteObjectRequest, CancellationToken cancellation) + { + var cmd = DeleteObjectCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, deleteObjectRequest.BucketName, deleteObjectRequest.Key), + deleteObjectRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task DeleteObjectsAsync(DeleteObjectsRequest deleteObjectsRequest, CancellationToken cancellation) + { + ThrowIfNullRequest(deleteObjectsRequest); + + var cmd = DeleteObjectsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, deleteObjectsRequest.BucketName, null), + deleteObjectsRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task DeleteObjectTaggingAsync(string bucketName, string key, CancellationToken cancellation) + { + await DeleteObjectTaggingAsync(new DeleteObjectTaggingRequest(bucketName, key), cancellation); + } + + /// + public async Task DeleteObjectTaggingAsync(DeleteObjectTaggingRequest request, CancellationToken cancellation) + { + var cmd = DeleteObjectTaggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, request.BucketName, request.Key), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task DeleteObjectVersionsAsync(DeleteObjectVersionsRequest deleteObjectVersionsRequest, CancellationToken cancellation) + { + ThrowIfNullRequest(deleteObjectVersionsRequest); + + var cmd = DeleteObjectVersionsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, deleteObjectVersionsRequest.BucketName, null), + deleteObjectVersionsRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task DoesObjectExistAsync(string bucketName, string key, CancellationToken cancellation) + { + try + { + var cmd = HeadObjectCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Head, bucketName, key), + bucketName, key); + + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + catch (OssException e) + { + if (e.ErrorCode == OssErrorCode.NoSuchBucket || + e.ErrorCode == OssErrorCode.NoSuchKey) + { + return false; + } + + // Rethrow + throw; + } + catch (WebException ex) + { + HttpWebResponse errorResponse = ex.Response as HttpWebResponse; + if (errorResponse.StatusCode == HttpStatusCode.NotFound) + { + return false; + } + + // Rethrow + throw; + } +#if NETCOREAPP2_0 + catch (System.Net.Http.HttpRequestException ex2) + { + if (ex2.Message.Contains("404")) + { + return false; + } + + throw; + } +#endif + return true; + } + + /// + public async Task GetObjectAclAsync(string bucketName, string key, CancellationToken cancellation) + { + return await GetObjectAclAsync(new GetObjectAclRequest(bucketName, key), cancellation); + } + + /// + public async Task GetObjectAclAsync(GetObjectAclRequest getObjectAclRequest, CancellationToken cancellation) + { + var cmd = GetObjectAclCommand.Create(_serviceClient, + _endpoint, + CreateContext(HttpMethod.Get, getObjectAclRequest.BucketName, getObjectAclRequest.Key), + getObjectAclRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetObjectAsync(string bucketName, string key, CancellationToken cancellation) + { + return await GetObjectAsync(new GetObjectRequest(bucketName, key), cancellation); + } + + /// + public async Task GetObjectAsync(Uri signedUrl, CancellationToken cancellation) + { + // prepare request + var request = new ServiceRequest + { + Method = HttpMethod.Get, + Endpoint = OssUtils.GetEndpointFromSignedUrl(signedUrl), + ResourcePath = OssUtils.GetResourcePathFromSignedUrl(signedUrl), + ParametersInUri = true + }; + var parameters = OssUtils.GetParametersFromSignedUrl(signedUrl); + foreach (var param in parameters) + { + request.Parameters.Add(param.Key, param.Value); + } + + // prepare context + var context = new ExecutionContext(); + context.Signer = null; + context.Credentials = null; + context.ResponseHandlers.Add(new ErrorResponseHandler()); + + // get response + var serviceResponse = await _serviceClient.SendAsync(request, context, cancellation); + + // build result + var getObjectRequest = new GetObjectRequest(null, null); + var ResponseDeserializer = new GetObjectResponseDeserializer(getObjectRequest, _serviceClient); + return ResponseDeserializer.Deserialize(serviceResponse); + } + + /// + public async Task GetObjectAsync(GetObjectRequest getObjectRequest, CancellationToken cancellation) + { + ThrowIfNullRequest(getObjectRequest); + + var cmd = GetObjectCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, getObjectRequest.BucketName, getObjectRequest.Key), + getObjectRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetObjectAsync(GetObjectRequest getObjectRequest, Stream output, CancellationToken cancellation) + { + var ossObject = await GetObjectAsync(getObjectRequest, cancellation); + using (ossObject.Content) + { + await IoUtils.WriteToAsync(ossObject.Content, output); + } + return ossObject.Metadata; + } + + /// + public async Task GetObjectMetadataAsync(string bucketName, string key, CancellationToken cancellation) + { + return await GetObjectMetadataAsync(new GetObjectMetadataRequest(bucketName, key), cancellation); + } + + /// + public async Task GetObjectMetadataAsync(GetObjectMetadataRequest request, CancellationToken cancellation) + { + var cmd = GetObjectMetadataCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Head, request.BucketName, request.Key), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetObjectTaggingAsync(string bucketName, string key, CancellationToken cancellation) + { + return await GetObjectTaggingAsync(new GetObjectTaggingRequest(bucketName, key), cancellation); + } + + /// + public async Task GetObjectTaggingAsync(GetObjectTaggingRequest request, CancellationToken cancellation) + { + var cmd = GetObjectTaggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, request.BucketName, request.Key), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetSimplifiedObjectMetadataAsync(GetObjectMetadataRequest request, CancellationToken cancellation) + { + var cmd = GetObjectMetadataCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Head, request.BucketName, request.Key), + request, true); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetSymlinkAsync(string bucketName, string symlink, CancellationToken cancellation) + { + var cmd = GetSymlinkCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, bucketName, symlink), + new GetSymlinkResultDeserializer(), + new GetSymlinkRequest(bucketName, symlink)); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetSymlinkAsync(GetSymlinkRequest getSymlinkRequest, CancellationToken cancellation) + { + var cmd = GetSymlinkCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, getSymlinkRequest.BucketName, getSymlinkRequest.Key), + new GetSymlinkResultDeserializer(), + getSymlinkRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task ListObjectsAsync(string bucketName, CancellationToken cancellation) + { + return await ListObjectsAsync(bucketName, null, cancellation); + } + + /// + public async Task ListObjectsAsync(string bucketName, string prefix, CancellationToken cancellation) + { + var listObjectsRequest = new ListObjectsRequest(bucketName) + { + Prefix = prefix + }; + return await ListObjectsAsync(listObjectsRequest,cancellation); + } + + /// + public async Task ListObjectsAsync(ListObjectsRequest listObjectsRequest, CancellationToken cancellation) + { + ThrowIfNullRequest(listObjectsRequest); + var cmd = ListObjectsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, listObjectsRequest.BucketName, null), + listObjectsRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task ListObjectVersionsAsync(ListObjectVersionsRequest listObjectVersionsRequest, CancellationToken cancellation) + { + ThrowIfNullRequest(listObjectVersionsRequest); + var cmd = ListObjectVersionsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, listObjectVersionsRequest.BucketName, null), + listObjectVersionsRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task ModifyObjectMetaAsync(string bucketName, string key, ObjectMetadata newMeta, long? partSize, string checkpointDir, CancellationToken cancellation) + { + var copyObjectRequest = new CopyObjectRequest(bucketName, key, bucketName, key) + { + NewObjectMetadata = newMeta + }; + await CopyBigObjectAsync(copyObjectRequest, partSize, checkpointDir, cancellation); + } + + /// + public async Task ProcessObjectAsync(ProcessObjectRequest request, CancellationToken cancellation) + { + ThrowIfNullRequest(request); + + var cmd = ProcessObjectCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, request.BucketName, request.Key), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task PutObjectAsync(string bucketName, string key, Stream content, CancellationToken cancellation) + { + return await PutObjectAsync(bucketName, key, content, null, cancellation); + } + + /// + public async Task PutObjectAsync(string bucketName, string key, Stream content, ObjectMetadata metadata, CancellationToken cancellation) + { + PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, content, metadata); + return await PutObjectAsync(putObjectRequest, cancellation); + } + + /// + public async Task PutObjectAsync(PutObjectRequest putObjectRequest, CancellationToken cancellation) + { + ObjectMetadata metadata = putObjectRequest.Metadata ?? new ObjectMetadata(); + SetContentTypeIfNull(putObjectRequest.Key, null, ref metadata); + putObjectRequest.Metadata = metadata; + + var cmd = PutObjectCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, putObjectRequest.BucketName, putObjectRequest.Key), + putObjectRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task PutObjectAsync(string bucketName, string key, string fileToUpload, CancellationToken cancellation) + { + return await PutObjectAsync(bucketName, key, fileToUpload, null, cancellation); + } + + /// + public async Task PutObjectAsync(string bucketName, string key, string fileToUpload, ObjectMetadata metadata, CancellationToken cancellation) + { + if (!File.Exists(fileToUpload) || Directory.Exists(fileToUpload)) + throw new ArgumentException(String.Format("Invalid file path {0}.", fileToUpload)); + + metadata = metadata ?? new ObjectMetadata(); + SetContentTypeIfNull(key, fileToUpload, ref metadata); + + PutObjectResult result; + using (Stream content = File.OpenRead(fileToUpload)) + { + result = await PutObjectAsync(bucketName, key, content, metadata, cancellation); + } + return result; + } + + /// + public async Task PutObjectAsync(Uri signedUrl, string fileToUpload, CancellationToken cancellation) + { + return await PutObjectAsync(signedUrl, fileToUpload, null, cancellation); + } + + /// + public async Task PutObjectAsync(Uri signedUrl, Stream content, CancellationToken cancellation) + { + return await PutObjectAsync(signedUrl, content, null, cancellation); + } + + /// + public async Task PutObjectAsync(Uri signedUrl, string fileToUpload, ObjectMetadata metadata, CancellationToken cancellation) + { + if (!File.Exists(fileToUpload) || Directory.Exists(fileToUpload)) + throw new ArgumentException(String.Format("Invalid file path {0}.", fileToUpload)); + + PutObjectResult result; + using (Stream content = File.OpenRead(fileToUpload)) + { + result = await PutObjectAsync(signedUrl, content, metadata, cancellation); + } + return result; + } + + /// + public async Task PutObjectAsync(Uri signedUrl, Stream content, ObjectMetadata metadata, CancellationToken cancellation) + { + // prepare request + var request = new ServiceRequest + { + Method = HttpMethod.Put, + Endpoint = OssUtils.GetEndpointFromSignedUrl(signedUrl), + ResourcePath = OssUtils.GetResourcePathFromSignedUrl(signedUrl), + ParametersInUri = true + }; + var parameters = OssUtils.GetParametersFromSignedUrl(signedUrl); + foreach (var param in parameters) + { + request.Parameters.Add(param.Key, param.Value); + } + request.Content = content; + + // populate headers + if (metadata != null) + { + //prevent to be assigned default value in metadata.Populate + if (metadata.ContentType == null) + { + request.Headers[HttpHeaders.ContentType] = ""; + } + metadata.Populate(request.Headers); + } + if (!request.Headers.ContainsKey(HttpHeaders.ContentLength)) + { + request.Headers[HttpHeaders.ContentLength] = content.Length.ToString(); + } + + // prepare context + var context = new ExecutionContext(); + context.Signer = null; + context.Credentials = null; + if (ObjectMetadata.HasCallbackHeader(metadata)) + { + context.ResponseHandlers.Add(new CallbackResponseHandler()); + } + else + { + context.ResponseHandlers.Add(new ErrorResponseHandler()); + } + + ClientConfiguration config = OssUtils.GetClientConfiguration(_serviceClient); + if (config.EnableCrcCheck) + { + var hashStream = new Crc64Stream(request.Content, null, request.Content.Length); + request.Content = hashStream; + context.ResponseHandlers.Add(new Crc64CheckHandler(hashStream)); + } + + // get response + var serviceResponse = await _serviceClient.SendAsync(request, context, cancellation); + + // build result + var putObjectRequest = new PutObjectRequest(null, null, null, metadata); + var ResponseDeserializer = new PutObjectResponseDeserializer(putObjectRequest); + return ResponseDeserializer.Deserialize(serviceResponse); + } + + /// + public async Task RestoreObjectAsync(string bucketName, string key, CancellationToken cancellation) + { + return await RestoreObjectAsync(new RestoreObjectRequest(bucketName, key), cancellation); + } + + /// + public async Task RestoreObjectAsync(RestoreObjectRequest restoreObjectRequest, CancellationToken cancellation) + { + ExecutionContext context = CreateContext(HttpMethod.Post, restoreObjectRequest.BucketName, restoreObjectRequest.Key); + var cmd = RestoreObjectCommand.Create(_serviceClient, + _endpoint, + context, + restoreObjectRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task ResumableCopyObjectAsync(CopyObjectRequest copyObjectRequest, string checkpointDir, long? partSize, CancellationToken cancellation) + { + return await ResumableCopyObjectAsync(copyObjectRequest, checkpointDir, partSize, cancellation); + } + + /// + public async Task ResumableDownloadObjectAsync(DownloadObjectRequest request, CancellationToken cancellation) + { + ThrowIfNullRequest(request); + ThrowIfNullRequest(request.BucketName); + ThrowIfNullRequest(request.Key); + ThrowIfNullRequest(request.DownloadFile); + + if (!Directory.GetParent(request.DownloadFile).Exists) + { + throw new ArgumentException(String.Format("Invalid file path {0}. The parent folder does not exist.", request.DownloadFile)); + } + + var metaRequest = new GetObjectMetadataRequest(request.BucketName, request.Key) + { + RequestPayer = request.RequestPayer, + VersionId = request.VersionId + }; + ObjectMetadata objectMeta = await this.GetObjectMetadataAsync(metaRequest,cancellation); + var fileSize = objectMeta.ContentLength; + + // Adjusts part size + long actualPartSize = AdjustPartSize(request.PartSize); + var config = OssUtils.GetClientConfiguration(_serviceClient); + if (fileSize <= actualPartSize) + { + using (Stream fs = File.Open(request.DownloadFile, FileMode.Create)) + { + using (var ossObject = await GetObjectAsync(request.ToGetObjectRequest(), cancellation)) + { + var streamWrapper = ossObject.Content; + try + { + if (config.EnalbeMD5Check && !string.IsNullOrEmpty(objectMeta.ContentMd5)) + { + byte[] expectedHashDigest = Convert.FromBase64String(objectMeta.ContentMd5); ; + streamWrapper = new MD5Stream(ossObject.Content, expectedHashDigest, fileSize); + } + else if (config.EnableCrcCheck && !string.IsNullOrEmpty(objectMeta.Crc64)) + { + if (ulong.TryParse(objectMeta.Crc64, out var crcVal)) + { + byte[] expectedHashDigest = BitConverter.GetBytes(crcVal); + streamWrapper = new Crc64Stream(ossObject.Content, expectedHashDigest, fileSize); + } + } + + if (request.StreamTransferProgress != null) + { + streamWrapper = this.SetupProgressListeners(streamWrapper, + objectMeta.ContentLength, + 0, + config.ProgressUpdateInterval, + request.StreamTransferProgress); + } + await ResumableDownloadManager.WriteToAsync(streamWrapper, fs,cancellation); + } + finally + { + if (!Object.Equals(streamWrapper, fs)) + { + streamWrapper.Dispose(); + } + } + } + } + + return objectMeta; + } + + ResumableDownloadContext resumableContext = this.LoadResumableDownloadContext(request.BucketName, request.Key, request.VersionId, objectMeta, request.CheckpointDir, actualPartSize); + ResumableDownloadManager resumableDownloadManager = new ResumableDownloadManager(this, ((RetryableServiceClient)_serviceClient).MaxRetryTimes, config); + resumableDownloadManager.ResumableDownloadWithRetry(request, resumableContext); + resumableContext.Clear(); + return objectMeta; + } + + /// + public async Task ResumableUploadObjectAsync(string bucketName, string key, string fileToUpload, ObjectMetadata metadata, string checkpointDir, long? partSize, EventHandler streamTransferProgress, CancellationToken cancellation) + { + if (!File.Exists(fileToUpload) || Directory.Exists(fileToUpload)) + throw new ArgumentException(String.Format("Invalid file path {0}.", fileToUpload)); + + // calculates content-type + metadata = metadata ?? new ObjectMetadata(); + SetContentTypeIfNull(key, fileToUpload, ref metadata); + + using (var fs = new FileStream(fileToUpload, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return await ResumableUploadObjectAsync(bucketName, key, fs, metadata, checkpointDir, partSize, streamTransferProgress,cancellation); + } + } + + /// + public async Task ResumableUploadObjectAsync(string bucketName, string key, Stream content, ObjectMetadata metadata, string checkpointDir, long? partSize, EventHandler streamTransferProgress, CancellationToken cancellation) + { + UploadObjectRequest request = new UploadObjectRequest(bucketName, key, content); + request.CheckpointDir = checkpointDir; + request.PartSize = partSize; + request.StreamTransferProgress = streamTransferProgress; + request.Metadata = metadata; + + return await ResumableUploadObjectAsync(request,cancellation); + } + + /// + public async Task ResumableUploadObjectAsync(UploadObjectRequest request, CancellationToken cancellation) + { + ThrowIfNullRequest(request); + ThrowIfNullRequest(request.BucketName); + ThrowIfNullRequest(request.Key); + if (string.IsNullOrEmpty(request.UploadFile) && request.UploadStream == null) + { + throw new ArgumentException("Parameter request.UploadFile or request.UploadStream must not be null."); + } + + if (request.UploadStream != null && !request.UploadStream.CanSeek) + { + throw new ArgumentException("Parameter request.UploadStream must be seekable---for nonseekable stream, please call UploadObject instead."); + } + + // calculates content-type + if (request.Metadata == null) + { + request.Metadata = new ObjectMetadata(); + } + + ObjectMetadata metadata = request.Metadata; + SetContentTypeIfNull(request.Key, null, ref metadata); + + // Adjust part size + long actualPartSize = AdjustPartSize(request.PartSize); + + // If the file size is less than the part size, upload it directly. + long fileSize = 0; + Stream uploadSteam = null; + + if (request.UploadStream != null) + { + fileSize = request.UploadStream.Length; + uploadSteam = request.UploadStream; + } + else + { + fileSize = new System.IO.FileInfo(request.UploadFile).Length; + uploadSteam = new FileStream(request.UploadFile, FileMode.Open, FileAccess.Read, FileShare.Read); + } + + if (fileSize <= actualPartSize) + { + try + { + var putObjectRequest = new PutObjectRequest(request.BucketName, request.Key, uploadSteam, metadata) + { + StreamTransferProgress = request.StreamTransferProgress, + RequestPayer = request.RequestPayer, + TrafficLimit = request.TrafficLimit + }; + return await PutObjectAsync(putObjectRequest, cancellation); + } + finally + { + uploadSteam.Dispose(); + } + } + + var resumableContext = LoadResumableUploadContext(request.BucketName, request.Key, uploadSteam, + request.CheckpointDir, actualPartSize); + + if (resumableContext.UploadId == null) + { + var initRequest = new InitiateMultipartUploadRequest(request.BucketName, request.Key, metadata) + { + RequestPayer = request.RequestPayer + }; + + var initResult = InitiateMultipartUpload(initRequest); + resumableContext.UploadId = initResult.UploadId; + } + + int maxRetry = ((RetryableServiceClient)_serviceClient).MaxRetryTimes; + ClientConfiguration config = OssUtils.GetClientConfiguration(_serviceClient); + ResumableUploadManager uploadManager = new ResumableUploadManager(this, maxRetry, config); + uploadManager.ResumableUploadWithRetry(request, resumableContext); + + // Completes the upload + var completeRequest = new CompleteMultipartUploadRequest(request.BucketName, request.Key, resumableContext.UploadId) + { + RequestPayer = request.RequestPayer + }; + if (metadata.HttpMetadata.ContainsKey(HttpHeaders.Callback)) + { + var callbackMetadata = new ObjectMetadata(); + callbackMetadata.AddHeader(HttpHeaders.Callback, metadata.HttpMetadata[HttpHeaders.Callback]); + completeRequest.Metadata = callbackMetadata; + } + + foreach (var part in resumableContext.PartContextList) + { + if (part == null || !part.IsCompleted) + { + throw new OssException("Not all parts are completed."); + } + + completeRequest.PartETags.Add(part.PartETag); + } + + PutObjectResult result = CompleteMultipartUpload(completeRequest); + resumableContext.Clear(); + + return result; + } + + /// + public async Task SelectObjectAsync(SelectObjectRequest request, CancellationToken cancellation) + { + ThrowIfNullRequest(request); + + var cmd = SelectObjectCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, request.BucketName, request.Key), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task SetObjectAclAsync(string bucketName, string key, CannedAccessControlList acl, CancellationToken cancellation) + { + var setObjectAclRequest = new SetObjectAclRequest(bucketName, key, acl); + await SetObjectAclAsync(setObjectAclRequest,cancellation); + } + + /// + public async Task SetObjectAclAsync(SetObjectAclRequest setObjectAclRequest, CancellationToken cancellation) + { + ThrowIfNullRequest(setObjectAclRequest); + + var cmd = SetObjectAclCommand.Create(_serviceClient, + _endpoint, + CreateContext(HttpMethod.Put, setObjectAclRequest.BucketName, setObjectAclRequest.Key), + setObjectAclRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetObjectTaggingAsync(SetObjectTaggingRequest request, CancellationToken cancellation) + { + ThrowIfNullRequest(request); + + var cmd = SetObjectTaggingCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, request.BucketName, request.Key), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + + #endregion + + #region Multipart Operations + /// + public async Task ListMultipartUploadsAsync(ListMultipartUploadsRequest listMultipartUploadsRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(listMultipartUploadsRequest); + var cmd = ListMultipartUploadsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, listMultipartUploadsRequest.BucketName, null), + listMultipartUploadsRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task InitiateMultipartUploadAsync(InitiateMultipartUploadRequest initiateMultipartUploadRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(initiateMultipartUploadRequest); + var cmd = InitiateMultipartUploadCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, initiateMultipartUploadRequest.BucketName, initiateMultipartUploadRequest.Key), + initiateMultipartUploadRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task AbortMultipartUploadAsync(AbortMultipartUploadRequest abortMultipartUploadRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(abortMultipartUploadRequest); + var cmd = AbortMultipartUploadCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, abortMultipartUploadRequest.BucketName, abortMultipartUploadRequest.Key), + abortMultipartUploadRequest); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task UploadPartAsync(UploadPartRequest uploadPartRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(uploadPartRequest); + var cmd = UploadPartCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, uploadPartRequest.BucketName, uploadPartRequest.Key), + uploadPartRequest); + return await cmd.ExecuteAsync(cancellation); + } + + + /// + public async Task UploadPartCopyAsync(UploadPartCopyRequest uploadPartCopyRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(uploadPartCopyRequest); + var cmd = UploadPartCopyCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, uploadPartCopyRequest.TargetBucket, uploadPartCopyRequest.TargetKey), + uploadPartCopyRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task ListPartsAsync(ListPartsRequest listPartsRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(listPartsRequest); + var cmd = ListPartsCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, listPartsRequest.BucketName, listPartsRequest.Key), + listPartsRequest); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task CompleteMultipartUploadAsync(CompleteMultipartUploadRequest completeMultipartUploadRequest, CancellationToken cancellation = default) + { + ThrowIfNullRequest(completeMultipartUploadRequest); + var cmd = CompleteMultipartUploadCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, completeMultipartUploadRequest.BucketName, completeMultipartUploadRequest.Key), + completeMultipartUploadRequest); + return await cmd.ExecuteAsync(cancellation); + } + + #endregion + + #region Live Channel + + /// + public async Task CreateLiveChannelAsync(CreateLiveChannelRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = CreateLiveChannelCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, request.BucketName, request.ChannelName), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task ListLiveChannelAsync(ListLiveChannelRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = ListLiveChannelCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, request.BucketName, null), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task DeleteLiveChannelAsync(DeleteLiveChannelRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = DeleteLiveChannelCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Delete, request.BucketName, request.ChannelName), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task SetLiveChannelStatusAsync(SetLiveChannelStatusRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = SetLiveChannelStatusCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Put, request.BucketName, request.ChannelName), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task GetLiveChannelInfoAsync(GetLiveChannelInfoRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = GetLiveChannelInfoCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, request.BucketName, request.ChannelName), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetLiveChannelStatAsync(GetLiveChannelStatRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = GetLiveChannelStatCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, request.BucketName, request.ChannelName), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task GetLiveChannelHistoryAsync(GetLiveChannelHistoryRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = GetLiveChannelHistoryCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, request.BucketName, request.ChannelName), + request); + return await cmd.ExecuteAsync(cancellation); + } + + /// + public async Task PostVodPlaylistAsync(PostVodPlaylistRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = PostVodPlaylistCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Post, request.BucketName, request.ChannelName + "/" + request.PlaylistName), + request); + using (await cmd.ExecuteAsync(cancellation)) + { + // Do nothing + } + } + + /// + public async Task GetVodPlaylistAsync(GetVodPlaylistRequest request, CancellationToken cancellation = default) + { + ThrowIfNullRequest(request); + var cmd = GetVodPlaylistCommand.Create(_serviceClient, _endpoint, + CreateContext(HttpMethod.Get, request.BucketName, request.ChannelName), + request); + return await cmd.ExecuteAsync(cancellation); + } + + #endregion + } +} diff --git a/sdk/OssClient.cs b/sdk/OssClient.cs index c5439d05..fa30550b 100644 --- a/sdk/OssClient.cs +++ b/sdk/OssClient.cs @@ -24,13 +24,14 @@ using Aliyun.OSS.Transform; using ExecutionContext = Aliyun.OSS.Common.Communication.ExecutionContext; using ICredentials = Aliyun.OSS.Common.Authentication.ICredentials; +using System.Threading.Tasks; namespace Aliyun.OSS { /// /// The OSS's access entry point interface's implementation. /// - public class OssClient : IOss + public partial class OssClient : IOss { #region Fields & Properties diff --git a/sdk/Util/IOUtils.cs b/sdk/Util/IOUtils.cs index 03d48008..ee373cc9 100644 --- a/sdk/Util/IOUtils.cs +++ b/sdk/Util/IOUtils.cs @@ -5,6 +5,8 @@ */ using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace Aliyun.OSS.Util { @@ -43,5 +45,38 @@ public static long WriteTo(Stream orignStream, Stream destStream, long totalSize return alreadyRead; } + + + public static async Task WriteToAsync(Stream src, Stream dest) + { + var buffer = new byte[BufferSize]; + int bytesRead; + while ((bytesRead = await src.ReadAsync(buffer, 0, buffer.Length)) > 0) + { + await dest.WriteAsync(buffer, 0, bytesRead); + } + await dest.FlushAsync(); + } + + public static async Task WriteToAsync(Stream orignStream, Stream destStream, long totalSize, CancellationToken cancellationToken=default) + { + var buffer = new byte[BufferSize]; + + long alreadyRead = 0; + while (alreadyRead < totalSize) + { + var readSize = await orignStream.ReadAsync(buffer, 0, BufferSize, cancellationToken); + if (readSize <= 0) + break; + + if (alreadyRead + readSize > totalSize) + readSize = (int)(totalSize - alreadyRead); + alreadyRead += readSize; + await destStream.WriteAsync(buffer, 0, readSize, cancellationToken); + } + await destStream.FlushAsync(); + + return alreadyRead; + } } } diff --git a/sdk/aliyun-oss-sdk-dotnetcore.csproj b/sdk/aliyun-oss-sdk-dotnetcore.csproj index 58b0ecc0..61dfba15 100644 --- a/sdk/aliyun-oss-sdk-dotnetcore.csproj +++ b/sdk/aliyun-oss-sdk-dotnetcore.csproj @@ -194,6 +194,7 @@ + @@ -222,6 +223,7 @@ + diff --git a/test/TestCase/OtherTestCase/ClassUnitTest.cs b/test/TestCase/OtherTestCase/ClassUnitTest.cs index f66d095d..a37e6f55 100644 --- a/test/TestCase/OtherTestCase/ClassUnitTest.cs +++ b/test/TestCase/OtherTestCase/ClassUnitTest.cs @@ -4,6 +4,8 @@ using System.IO; using System.Net; using System.Text; +using System.Threading; +using System.Threading.Tasks; using Aliyun.OSS.Common; using Aliyun.OSS.Common.Authentication; using Aliyun.OSS.Common.Communication; @@ -13,6 +15,7 @@ using Aliyun.OSS.Transform; using Aliyun.OSS.Util; using NUnit.Framework; +using ExecutionContext = Aliyun.OSS.Common.Communication.ExecutionContext; namespace Aliyun.OSS.Test.TestClass.OtherTestClass { @@ -419,10 +422,10 @@ public void SetBucketLifecycleRequestTest() { var request = new SetBucketLifecycleRequest("bucket"); var rule = new LifecycleRule(); - rule.ID = "StandardExpireRule"; - rule.Prefix = "test"; - rule.Status = RuleStatus.Enabled; - rule.ExpriationDays = 200; + rule.ID = "StandardExpireRule"; + rule.Prefix = "test"; + rule.Status = RuleStatus.Enabled; + rule.ExpriationDays = 200; var rules = new List(); @@ -852,29 +855,29 @@ public void LifecycleRuleTest() Assert.AreEqual(rule1.Equals(rule1f), true); Assert.AreEqual(rule1.Equals(null), false); - rule1.ID = "RuleID"; - rule1.Prefix = "test"; - rule2.ID = "RuleID"; - rule2.Prefix = "test"; + rule1.ID = "RuleID"; + rule1.Prefix = "test"; + rule2.ID = "RuleID"; + rule2.Prefix = "test"; Assert.AreEqual(rule1.Equals(rule2), true); - rule1.ID = "RuleID"; - rule1.Prefix = "test"; - rule2.ID = "RuleID1"; - rule2.Prefix = "test"; + rule1.ID = "RuleID"; + rule1.Prefix = "test"; + rule2.ID = "RuleID1"; + rule2.Prefix = "test"; Assert.AreEqual(rule1.Equals(rule2), false); - rule1.ID = "RuleID"; - rule1.Prefix = "test"; - rule2.ID = "RuleID"; - rule2.Prefix = "test1"; + rule1.ID = "RuleID"; + rule1.Prefix = "test"; + rule2.ID = "RuleID"; + rule2.Prefix = "test1"; Assert.AreEqual(rule1.Equals(rule2), false); - rule1.ID = "RuleID"; - rule1.Prefix = "test"; - rule2.ID = "RuleID"; - rule2.Prefix = "test"; - rule1.ExpriationDays = 200; + rule1.ID = "RuleID"; + rule1.Prefix = "test"; + rule2.ID = "RuleID"; + rule2.Prefix = "test"; + rule1.ExpriationDays = 200; Assert.AreEqual(rule1.Equals(rule2), false); rule2.ExpriationDays = rule1.ExpriationDays; @@ -914,21 +917,21 @@ public void LifecycleRuleTest() Assert.AreEqual(rule1.Equals(rule2), false); rule1.Transitions = new LifecycleRule.LifeCycleTransition[2] - { - new LifecycleRule.LifeCycleTransition(){ - StorageClass = StorageClass.IA - }, - new LifecycleRule.LifeCycleTransition(){ - StorageClass = StorageClass.Archive + { + new LifecycleRule.LifeCycleTransition(){ + StorageClass = StorageClass.IA + }, + new LifecycleRule.LifeCycleTransition(){ + StorageClass = StorageClass.Archive } }; rule2.Transitions = new LifecycleRule.LifeCycleTransition[2] - { - new LifecycleRule.LifeCycleTransition(){ - StorageClass = StorageClass.Archive - }, - new LifecycleRule.LifeCycleTransition(){ - StorageClass = StorageClass.Archive + { + new LifecycleRule.LifeCycleTransition(){ + StorageClass = StorageClass.Archive + }, + new LifecycleRule.LifeCycleTransition(){ + StorageClass = StorageClass.Archive } }; Assert.AreEqual(rule1.Equals(rule2), false); @@ -963,52 +966,52 @@ public void LifecycleRuleTest() Assert.AreEqual(transition1.Equals(transition2), false); //Tags - LifecycleRule rulet1 = new LifecycleRule(); - rulet1.ID = "StandardExpireRule"; - rulet1.Prefix = "test"; - rulet1.Status = RuleStatus.Enabled; - rulet1.ExpriationDays = 200; - - LifecycleRule rulet2 = new LifecycleRule(); - rulet2.ID = "StandardExpireRule"; - rulet2.Prefix = "test"; - rulet2.Status = RuleStatus.Enabled; - rulet2.ExpriationDays = 200; - rulet2.Tags = new Tag[1] - { - new Tag(){ - Key = "key1", - Value = "value1" - } - }; + LifecycleRule rulet1 = new LifecycleRule(); + rulet1.ID = "StandardExpireRule"; + rulet1.Prefix = "test"; + rulet1.Status = RuleStatus.Enabled; + rulet1.ExpriationDays = 200; + + LifecycleRule rulet2 = new LifecycleRule(); + rulet2.ID = "StandardExpireRule"; + rulet2.Prefix = "test"; + rulet2.Status = RuleStatus.Enabled; + rulet2.ExpriationDays = 200; + rulet2.Tags = new Tag[1] + { + new Tag(){ + Key = "key1", + Value = "value1" + } + }; Assert.AreNotEqual(rulet1, rulet2); Assert.AreNotEqual(rulet2, rulet1); rulet1.Tags = new Tag[1] - { - new Tag(){ - Key = "key1", - Value = "value1" + { + new Tag(){ + Key = "key1", + Value = "value1" } }; rulet2.Tags = new Tag[1] - { - new Tag(){ - Key = "key2", - Value = "value2" + { + new Tag(){ + Key = "key2", + Value = "value2" } }; Assert.AreNotEqual(rulet1, rulet2); rulet2.Tags = new Tag[2] - { - new Tag(){ - Key = "key1", - Value = "value1" - }, - new Tag(){ - Key = "key2", - Value = "value2" + { + new Tag(){ + Key = "key1", + Value = "value1" + }, + new Tag(){ + Key = "key2", + Value = "value2" } }; Assert.AreNotEqual(rulet1, rulet2); @@ -1018,15 +1021,15 @@ public void LifecycleRuleTest() //ExpiredObjectDeleteMarker LifecycleRule rulev1 = new LifecycleRule(); - rulev1.ID = "StandardExpireRule"; - rulev1.Prefix = "test"; - rulev1.Status = RuleStatus.Enabled; + rulev1.ID = "StandardExpireRule"; + rulev1.Prefix = "test"; + rulev1.Status = RuleStatus.Enabled; rulev1.ExpiredObjectDeleteMarker = false; LifecycleRule rulev2 = new LifecycleRule(); - rulev2.ID = "StandardExpireRule"; - rulev2.Prefix = "test"; - rulev2.Status = RuleStatus.Enabled; + rulev2.ID = "StandardExpireRule"; + rulev2.Prefix = "test"; + rulev2.Status = RuleStatus.Enabled; rulev2.ExpiredObjectDeleteMarker = false; Assert.AreEqual(rulev1, rulev2); @@ -1038,22 +1041,22 @@ public void LifecycleRuleTest() //NoncurrentVersionExpiration LifecycleRule ruleve1 = new LifecycleRule(); - ruleve1.ID = "StandardExpireRule"; - ruleve1.Prefix = "test"; - ruleve1.Status = RuleStatus.Enabled; + ruleve1.ID = "StandardExpireRule"; + ruleve1.Prefix = "test"; + ruleve1.Status = RuleStatus.Enabled; ruleve1.NoncurrentVersionExpiration = new LifecycleRule.LifeCycleNoncurrentVersionExpiration() { NoncurrentDays = 100 - }; + }; LifecycleRule ruleve2 = new LifecycleRule(); - ruleve2.ID = "StandardExpireRule"; - ruleve2.Prefix = "test"; + ruleve2.ID = "StandardExpireRule"; + ruleve2.Prefix = "test"; ruleve2.Status = RuleStatus.Enabled; ruleve2.NoncurrentVersionExpiration = new LifecycleRule.LifeCycleNoncurrentVersionExpiration() { NoncurrentDays = 100 - }; + }; Assert.AreEqual(ruleve1, ruleve2); ruleve2.NoncurrentVersionExpiration.NoncurrentDays = 200; @@ -1070,35 +1073,35 @@ public void LifecycleRuleTest() //NoncurrentVersionTransitions LifecycleRule rulevt1 = new LifecycleRule(); - rulevt1.ID = "StandardExpireRule"; - rulevt1.Prefix = "test"; - rulevt1.Status = RuleStatus.Enabled; + rulevt1.ID = "StandardExpireRule"; + rulevt1.Prefix = "test"; + rulevt1.Status = RuleStatus.Enabled; rulevt1.NoncurrentVersionTransitions = new LifecycleRule.LifeCycleNoncurrentVersionTransition[2] - { - new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ - StorageClass = StorageClass.IA, - NoncurrentDays = 90 - }, - new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ - StorageClass = StorageClass.Archive, - NoncurrentDays = 180 - } - }; + { + new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ + StorageClass = StorageClass.IA, + NoncurrentDays = 90 + }, + new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ + StorageClass = StorageClass.Archive, + NoncurrentDays = 180 + } + }; LifecycleRule rulevt2 = new LifecycleRule(); - rulevt2.ID = "StandardExpireRule"; - rulevt2.Prefix = "test"; + rulevt2.ID = "StandardExpireRule"; + rulevt2.Prefix = "test"; rulevt2.Status = RuleStatus.Enabled; rulevt2.NoncurrentVersionTransitions = new LifecycleRule.LifeCycleNoncurrentVersionTransition[2] - { - new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ - StorageClass = StorageClass.IA, - NoncurrentDays = 90 - }, - new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ - StorageClass = StorageClass.Archive, - NoncurrentDays = 180 - } + { + new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ + StorageClass = StorageClass.IA, + NoncurrentDays = 90 + }, + new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ + StorageClass = StorageClass.Archive, + NoncurrentDays = 180 + } }; Assert.AreEqual(rulevt1, rulevt2); @@ -1106,11 +1109,11 @@ public void LifecycleRuleTest() Assert.AreNotEqual(ruleve1, rulevt2); ruleve2.NoncurrentVersionTransitions = new LifecycleRule.LifeCycleNoncurrentVersionTransition[1] - { - new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ - StorageClass = StorageClass.IA, - NoncurrentDays = 90 - } + { + new LifecycleRule.LifeCycleNoncurrentVersionTransition(){ + StorageClass = StorageClass.IA, + NoncurrentDays = 90 + } }; Assert.AreNotEqual(rulevt1, rulevt2); @@ -1392,6 +1395,11 @@ protected override ServiceResponse SendCore(ServiceRequest request, ExecutionCon { throw new NotImplementedException(); } + + protected override Task SendCoreAsync(ServiceRequest request, Common.Communication.ExecutionContext context, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } } @@ -2961,36 +2969,36 @@ public void GetBucketInventoryConfigurationResultDeserializerTest() var headers = new Dictionary(); string data = @" - - report1 - true - - - CSV - 1000000000000000 - acs:ram::1000000000000000:role/bucket-inventory-role - acs:oss:::bucket_0001 - prefix1 - - - - - - - Daily - - - myprefix/ - - All - - Size - LastModifiedDate - StorageClass - IsMultipartUploaded - EncryptionStatus - ETag - + + report1 + true + + + CSV + 1000000000000000 + acs:ram::1000000000000000:role/bucket-inventory-role + acs:oss:::bucket_0001 + prefix1 + + + + + + + Daily + + + myprefix/ + + All + + Size + LastModifiedDate + StorageClass + IsMultipartUploaded + EncryptionStatus + ETag + "; var content = new MemoryStream(Encoding.ASCII.GetBytes(data)); @@ -3018,27 +3026,27 @@ public void GetBucketInventoryConfigurationResultDeserializerTest() data = @" - - report1 - false - - - CSV - 1000000000000000 - acs:ram::1000000000000000:role/bucket-inventory-role - acs:oss:::bucket_0001 - prefix1 - - - - - - - Weekly - - Current - - + + report1 + false + + + CSV + 1000000000000000 + acs:ram::1000000000000000:role/bucket-inventory-role + acs:oss:::bucket_0001 + prefix1 + + + + + + + Weekly + + Current + + "; content = new MemoryStream(Encoding.ASCII.GetBytes(data)); @@ -3056,29 +3064,29 @@ public void GetBucketInventoryConfigurationResultDeserializerTest() data = @" - - report1 - false - - - CSV - 1000000000000000 - acs:ram::1000000000000000:role/bucket-inventory-role - acs:oss:::bucket_0001 - prefix1 - + + report1 + false + + + CSV + 1000000000000000 + acs:ram::1000000000000000:role/bucket-inventory-role + acs:oss:::bucket_0001 + prefix1 + keyId - - - - - - Weekly - - Current - - + + + + + + Weekly + + Current + + "; content = new MemoryStream(Encoding.ASCII.GetBytes(data)); @@ -3091,24 +3099,24 @@ public void GetBucketInventoryConfigurationResultDeserializerTest() data = @" - - report1 - true - - - CSV - 1000000000000000 - acs:ram::1000000000000000:role/bucket-inventory-role - acs:oss:::bucket_0001 - prefix1 - - - - - - Daily - - All + + report1 + true + + + CSV + 1000000000000000 + acs:ram::1000000000000000:role/bucket-inventory-role + acs:oss:::bucket_0001 + prefix1 + + + + + + Daily + + All "; content = new MemoryStream(Encoding.ASCII.GetBytes(data)); @@ -3120,11 +3128,11 @@ public void GetBucketInventoryConfigurationResultDeserializerTest() data = @" - - - - - + + + + + "; content = new MemoryStream(Encoding.ASCII.GetBytes(data)); @@ -3170,85 +3178,85 @@ public void ListBucketInventoryConfigurationResultDeserializerTest() var headers = new Dictionary(); string data = @" - - - report1 - true - - - CSV - 1000000000000000 - acs:ram::1000000000000000:role/bucket-inventory-role - acs:oss:::destination-bucket - prefix1 - - - - Daily - - - prefix/One - - All - - Size - LastModifiedDate - StorageClass - IsMultipartUploaded - EncryptionStatus - ETag - - - - report2 - true - - - CSV - 1000000000000000 - acs:ram::1000000000000000:role/bucket-inventory-role - acs:oss:::destination-bucket - prefix2 - - - - Daily - - - prefix/Two - - All - - Size - LastModifiedDate - ETag - StorageClass - IsMultipartUploaded - EncryptionStatus - - - - report3 - false - - - CSV - 1000000000000000 - acs:ram::1000000000000000:role/bucket-inventory-role - acs:oss:::destination-bucket - prefix3 - - - - Daily - - - prefix/Three - - All - - true - report2 + + + report1 + true + + + CSV + 1000000000000000 + acs:ram::1000000000000000:role/bucket-inventory-role + acs:oss:::destination-bucket + prefix1 + + + + Daily + + + prefix/One + + All + + Size + LastModifiedDate + StorageClass + IsMultipartUploaded + EncryptionStatus + ETag + + + + report2 + true + + + CSV + 1000000000000000 + acs:ram::1000000000000000:role/bucket-inventory-role + acs:oss:::destination-bucket + prefix2 + + + + Daily + + + prefix/Two + + All + + Size + LastModifiedDate + ETag + StorageClass + IsMultipartUploaded + EncryptionStatus + + + + report3 + false + + + CSV + 1000000000000000 + acs:ram::1000000000000000:role/bucket-inventory-role + acs:oss:::destination-bucket + prefix3 + + + + Daily + + + prefix/Three + + All + + true + report2 "; var content = new MemoryStream(Encoding.ASCII.GetBytes(data)); @@ -3284,9 +3292,9 @@ public void ListBucketInventoryConfigurationResultDeserializerTest() data = @" - - false - + + false + "; content = new MemoryStream(Encoding.ASCII.GetBytes(data)); @@ -3718,7 +3726,7 @@ public void SelectObjectRequestDeserializerTest() } } - [Test] + [Test] public void SelectObjectCSVInputFormatTest() { var inputFormat = new SelectObjectCSVInputFormat(); @@ -3734,7 +3742,7 @@ public void SelectObjectCSVInputFormatTest() Assert.AreEqual(CompressionType.None, inputFormat.CompressionType); } - [Test] + [Test] public void SelectObjectCSVOutputFormatTest() { var outputFormat = new SelectObjectCSVOutputFormat(); @@ -3747,7 +3755,7 @@ public void SelectObjectCSVOutputFormatTest() Assert.AreEqual(null, outputFormat.OutputHeader); } - [Test] + [Test] public void SelectObjectOptionsTest() { var options = new SelectObjectOptions(); @@ -3755,7 +3763,7 @@ public void SelectObjectOptionsTest() Assert.AreEqual(null, options.MaxSkippedRecordsAllowed); } - [Test] + [Test] public void SelectObjectJSONInputFormatTest() { var inputFormat = new SelectObjectJSONInputFormat(); @@ -3766,7 +3774,7 @@ public void SelectObjectJSONInputFormatTest() Assert.AreEqual(CompressionType.None, inputFormat.CompressionType); } - [Test] + [Test] public void SelectObjectJSONOutputFormatTest() { var outputFormat = new SelectObjectJSONOutputFormat(); @@ -3963,7 +3971,7 @@ public void CreateSelectObjectRequestSerializerTest() Assert.AreEqual(str.Contains("