diff --git a/ManagedCode.Storage.Aws/AWSStorage.cs b/ManagedCode.Storage.Aws/AWSStorage.cs index e22d8632..2f963e37 100644 --- a/ManagedCode.Storage.Aws/AWSStorage.cs +++ b/ManagedCode.Storage.Aws/AWSStorage.cs @@ -306,24 +306,30 @@ private async Task UploadStreamInternalAsync(string blobName, Stream dataStream, BucketName = _bucket, Key = blobName, InputStream = dataStream, - AutoCloseStream = true, + AutoCloseStream = false, ContentType = contentType ?? Constants.ContentType, ServerSideEncryptionMethod = null }; - await _s3Client.EnsureBucketExistsAsync(_bucket); - await _s3Client.PutObjectAsync(putRequest, cancellationToken); + try + { + await _s3Client.PutObjectAsync(putRequest, cancellationToken); + } + catch (AmazonS3Exception) + { + await CreateContainerAsync(); + await _s3Client.PutObjectAsync(putRequest, cancellationToken); + } } #endregion #region CreateContainer - public async Task CreateContainerAsync() + public async Task CreateContainerAsync(CancellationToken cancellationToken = default) { await _s3Client.EnsureBucketExistsAsync(_bucket); } #endregion - } \ No newline at end of file diff --git a/ManagedCode.Storage.Azure/AzureStorage.cs b/ManagedCode.Storage.Azure/AzureStorage.cs index 41871ca0..523e0a9b 100644 --- a/ManagedCode.Storage.Azure/AzureStorage.cs +++ b/ManagedCode.Storage.Azure/AzureStorage.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Azure; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using ManagedCode.Storage.Azure.Options; @@ -26,14 +27,6 @@ public AzureStorage(AzureStorageOptions options) options.Container, options.OriginalOptions ); - - - if (_options.ShouldCreateIfNotExists) - { - _blobContainerClient.CreateIfNotExists(PublicAccessType.BlobContainer); - } - - _blobContainerClient.SetAccessPolicy(_options.PublicAccessType); } public void Dispose() @@ -188,13 +181,31 @@ public async IAsyncEnumerable GetBlobListAsync(CancellationToken c public async Task UploadStreamAsync(string blobName, Stream dataStream, CancellationToken cancellationToken = default) { var blobClient = _blobContainerClient.GetBlobClient(blobName); - await blobClient.UploadAsync(dataStream, cancellationToken); + + try + { + await blobClient.UploadAsync(dataStream, cancellationToken); + } + catch (RequestFailedException) + { + await CreateContainerAsync(); + await blobClient.UploadAsync(dataStream, cancellationToken); + } } public async Task UploadAsync(string blobName, string content, CancellationToken cancellationToken = default) { var blobClient = _blobContainerClient.GetBlobClient(blobName); - await blobClient.UploadAsync(BinaryData.FromString(content), cancellationToken); + + try + { + await blobClient.UploadAsync(BinaryData.FromString(content), cancellationToken); + } + catch (RequestFailedException) + { + await CreateContainerAsync(); + await blobClient.UploadAsync(BinaryData.FromString(content), cancellationToken); + } } public async Task UploadFileAsync(string blobName, string pathToFile, CancellationToken cancellationToken = default) @@ -203,7 +214,15 @@ public async Task UploadFileAsync(string blobName, string pathToFile, Cancellati using (var fs = new FileStream(pathToFile, FileMode.Open, FileAccess.Read)) { - await blobClient.UploadAsync(fs, cancellationToken); + try + { + await blobClient.UploadAsync(fs, cancellationToken); + } + catch (RequestFailedException) + { + await CreateContainerAsync(); + await blobClient.UploadAsync(fs, cancellationToken); + } } } @@ -225,7 +244,16 @@ public async Task UploadAsync(BlobMetadata blobMetadata, string content, Cancell public async Task UploadAsync(BlobMetadata blobMetadata, byte[] data, CancellationToken cancellationToken = default) { var blobClient = _blobContainerClient.GetBlobClient(blobMetadata.Name); - await blobClient.UploadAsync(BinaryData.FromBytes(data), cancellationToken); + + try + { + await blobClient.UploadAsync(BinaryData.FromBytes(data), cancellationToken); + } + catch (RequestFailedException) + { + await CreateContainerAsync(); + await blobClient.UploadAsync(BinaryData.FromBytes(data), cancellationToken); + } } public async Task UploadAsync(string content, CancellationToken cancellationToken = default) @@ -233,17 +261,34 @@ public async Task UploadAsync(string content, CancellationToken cancella string fileName = $"{Guid.NewGuid().ToString("N").ToLowerInvariant()}.txt"; var blobClient = _blobContainerClient.GetBlobClient(fileName); - await blobClient.UploadAsync(BinaryData.FromString(content), cancellationToken); + try + { + await blobClient.UploadAsync(BinaryData.FromString(content), cancellationToken); + } + catch (RequestFailedException) + { + await CreateContainerAsync(); + await blobClient.UploadAsync(BinaryData.FromString(content), cancellationToken); + } + return fileName; } public async Task UploadAsync(Stream dataStream, CancellationToken cancellationToken = default) { - string fileName = Guid.NewGuid().ToString("N").ToLowerInvariant(); - + var fileName = Guid.NewGuid().ToString("N").ToLowerInvariant(); var blobClient = _blobContainerClient.GetBlobClient(fileName); - await blobClient.UploadAsync(dataStream, cancellationToken); + + try + { + await blobClient.UploadAsync(dataStream, cancellationToken); + } + catch (RequestFailedException) + { + await CreateContainerAsync(); + await blobClient.UploadAsync(dataStream, cancellationToken); + } return fileName; } @@ -252,17 +297,15 @@ public async Task UploadAsync(Stream dataStream, CancellationToken cance #region CreateContainer - public async Task CreateContainerAsync() + public async Task CreateContainerAsync(CancellationToken cancellationToken = default) { - if (_options.ShouldCreateIfNotExists) { - await _blobContainerClient.CreateIfNotExistsAsync(PublicAccessType.BlobContainer); + await _blobContainerClient.CreateIfNotExistsAsync(PublicAccessType.BlobContainer, cancellationToken: cancellationToken); } await _blobContainerClient.SetAccessPolicyAsync(_options.PublicAccessType); } #endregion - } \ No newline at end of file diff --git a/ManagedCode.Storage.Core/IStorage.cs b/ManagedCode.Storage.Core/IStorage.cs index bc295610..f1e80930 100644 --- a/ManagedCode.Storage.Core/IStorage.cs +++ b/ManagedCode.Storage.Core/IStorage.cs @@ -38,5 +38,5 @@ public interface IStorage : IDisposable IAsyncEnumerable ExistsAsync(IEnumerable blobNames, CancellationToken cancellationToken = default); IAsyncEnumerable ExistsAsync(IEnumerable blobs, CancellationToken cancellationToken = default); - Task CreateContainerAsync(); + Task CreateContainerAsync(CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/ManagedCode.Storage.FileSystem/FileSystemStorage.cs b/ManagedCode.Storage.FileSystem/FileSystemStorage.cs index 8ef8f1f8..80545e3d 100644 --- a/ManagedCode.Storage.FileSystem/FileSystemStorage.cs +++ b/ManagedCode.Storage.FileSystem/FileSystemStorage.cs @@ -257,7 +257,7 @@ public async Task UploadAsync(Stream dataStream, CancellationToken cance #region CreateContainer - public async Task CreateContainerAsync() + public async Task CreateContainerAsync(CancellationToken cancellationToken = default) { await Task.Yield(); @@ -268,5 +268,4 @@ public async Task CreateContainerAsync() } #endregion - } \ No newline at end of file diff --git a/ManagedCode.Storage.Gcp/GCPStorage.cs b/ManagedCode.Storage.Gcp/GCPStorage.cs index 0230d580..0d0b4ae6 100644 --- a/ManagedCode.Storage.Gcp/GCPStorage.cs +++ b/ManagedCode.Storage.Gcp/GCPStorage.cs @@ -34,21 +34,6 @@ public GCPStorage(GCPStorageOptions gcpStorageOptions) { _storageClient = StorageClient.Create(gcpStorageOptions.GoogleCredential); } - - try - { - if (_gcpStorageOptions.OriginalOptions != null) - { - _storageClient.CreateBucket(_gcpStorageOptions.BucketOptions.ProjectId, _bucket, _gcpStorageOptions.OriginalOptions); - } - else - { - _storageClient.CreateBucket(_gcpStorageOptions.BucketOptions.ProjectId, _bucket); - } - } - catch - { - } } public void Dispose() @@ -262,28 +247,33 @@ private async Task UploadStreamInternalAsync(string blobName, Stream dataStream, CancellationToken cancellationToken = default) { contentType ??= Constants.ContentType; - await _storageClient.UploadObjectAsync(_bucket, blobName, contentType, dataStream, null, cancellationToken); + + try + { + await _storageClient.UploadObjectAsync(_bucket, blobName, contentType, dataStream, null, cancellationToken); + } + catch + { + await CreateContainerAsync(); + await _storageClient.UploadObjectAsync(_bucket, blobName, contentType, dataStream, null, cancellationToken); + } } #endregion #region CreateContainer - public async Task CreateContainerAsync() + + public async Task CreateContainerAsync(CancellationToken cancellationToken = default) { - try + if (_gcpStorageOptions.OriginalOptions != null) { - if (_gcpStorageOptions.OriginalOptions != null) - { - await _storageClient.CreateBucketAsync(_gcpStorageOptions.BucketOptions.ProjectId, _bucket, _gcpStorageOptions.OriginalOptions); - } - else - { - await _storageClient.CreateBucketAsync(_gcpStorageOptions.BucketOptions.ProjectId, _bucket); - } + await _storageClient.CreateBucketAsync(_gcpStorageOptions.BucketOptions.ProjectId, _bucket, _gcpStorageOptions.OriginalOptions, cancellationToken); } - catch + else { + await _storageClient.CreateBucketAsync(_gcpStorageOptions.BucketOptions.ProjectId, _bucket, cancellationToken: cancellationToken); } } + #endregion } \ No newline at end of file diff --git a/ManagedCode.Storage.Tests/StorageBaseTests.cs b/ManagedCode.Storage.Tests/StorageBaseTests.cs index 14af7813..d3bcd80d 100644 --- a/ManagedCode.Storage.Tests/StorageBaseTests.cs +++ b/ManagedCode.Storage.Tests/StorageBaseTests.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -602,6 +603,18 @@ public async Task ExistFileByListBlobMetadataAsync() #endregion + #region CreateContainer + + [Fact] + public async Task CreateContainerAsync() + { + await FluentActions.Awaiting(() => Storage.CreateContainerAsync()) + .Should().NotThrowAsync(); + } + + #endregion + + private async Task PrepareFileToTest(string content, string fileName) { if (await Storage.ExistsAsync(fileName))