From 435703fd6d2392737cc53327a2e1334305d93dc4 Mon Sep 17 00:00:00 2001 From: dtymakhov Date: Wed, 27 Jul 2022 21:25:38 +0300 Subject: [PATCH 1/2] Upgraded Communication package --- .../StorageExtensions.cs | 4 +-- .../ManagedCode.Storage.Aws.csproj | 2 +- ManagedCode.Storage.Azure/AzureStorage.cs | 27 +++++++------- .../ManagedCode.Storage.Azure.csproj | 2 +- .../AzureDataLakeStorage.cs | 4 +-- .../ManagedCode.Storage.AzureDataLake.csproj | 2 +- .../ManagedCode.Storage.Core.csproj | 2 +- .../FileSystemStorage.cs | 35 +++++++++---------- .../ManagedCode.Storage.FileSystem.csproj | 2 +- .../ManagedCode.Storage.Gcp.csproj | 2 +- .../ManagedCode.Storage.Tests.csproj | 2 +- 11 files changed, 41 insertions(+), 43 deletions(-) diff --git a/ManagedCode.Storage.AspNetExtensions/StorageExtensions.cs b/ManagedCode.Storage.AspNetExtensions/StorageExtensions.cs index 5fd60ece..324bdbaa 100644 --- a/ManagedCode.Storage.AspNetExtensions/StorageExtensions.cs +++ b/ManagedCode.Storage.AspNetExtensions/StorageExtensions.cs @@ -49,7 +49,7 @@ public static async Task> DownloadAsFileResult(this IStorage if (result.IsError) { - return Result.Fail(result.Error); + return Result.Fail(result.Error!); } var fileStream = new FileStreamResult(result.Value!.FileStream, MimeHelper.GetMimeType(result.Value.FileInfo.Extension)) @@ -67,7 +67,7 @@ public static async Task> DownloadAsFileResult(this IStorage if (result.IsError) { - return Result.Fail(result.Error); + return Result.Fail(result.Error!); } var fileStream = new FileStreamResult(result.Value!.FileStream, MimeHelper.GetMimeType(result.Value.FileInfo.Extension)) diff --git a/ManagedCode.Storage.Aws/ManagedCode.Storage.Aws.csproj b/ManagedCode.Storage.Aws/ManagedCode.Storage.Aws.csproj index 5efbe863..46e2e365 100644 --- a/ManagedCode.Storage.Aws/ManagedCode.Storage.Aws.csproj +++ b/ManagedCode.Storage.Aws/ManagedCode.Storage.Aws.csproj @@ -21,7 +21,7 @@ - + diff --git a/ManagedCode.Storage.Azure/AzureStorage.cs b/ManagedCode.Storage.Azure/AzureStorage.cs index 7591d188..d58848a6 100644 --- a/ManagedCode.Storage.Azure/AzureStorage.cs +++ b/ManagedCode.Storage.Azure/AzureStorage.cs @@ -186,20 +186,20 @@ protected override async Task> GetBlobMetadataInternalAsync var blobClient = StorageClient.GetBlobClient(options.FullPath); var properties = await blobClient.GetPropertiesAsync(cancellationToken: cancellationToken); - if (properties != null) + if (properties is null) { - return Result.Succeed(new BlobMetadata - { - Name = blobClient.Name, - Uri = blobClient.Uri, - Container = blobClient.BlobContainerName, - Length = properties.Value.ContentLength, - Metadata = properties.Value.Metadata.ToDictionary(k => k.Key, v => v.Value), - MimeType = properties.Value.ContentType - }); + return Result.Fail("Properties for file not found"); } - return Result.Fail(); + return Result.Succeed(new BlobMetadata + { + Name = blobClient.Name, + Uri = blobClient.Uri, + Container = blobClient.BlobContainerName, + Length = properties.Value.ContentLength, + Metadata = properties.Value.Metadata.ToDictionary(k => k.Key, v => v.Value), + MimeType = properties.Value.ContentType + }); } catch (Exception ex) { @@ -238,8 +238,9 @@ protected override async Task SetLegalHoldInternalAsync(bool hasLegalHol { await EnsureContainerExist(); var blobClient = StorageClient.GetBlobClient(options.FullPath); - var response = await blobClient.SetLegalHoldAsync(hasLegalHold, cancellationToken); - return response.Value.HasLegalHold ? Result.Succeed() : Result.Fail(); + await blobClient.SetLegalHoldAsync(hasLegalHold, cancellationToken); + + return Result.Succeed(); } catch (Exception ex) { diff --git a/ManagedCode.Storage.Azure/ManagedCode.Storage.Azure.csproj b/ManagedCode.Storage.Azure/ManagedCode.Storage.Azure.csproj index 3fdaf541..996646be 100644 --- a/ManagedCode.Storage.Azure/ManagedCode.Storage.Azure.csproj +++ b/ManagedCode.Storage.Azure/ManagedCode.Storage.Azure.csproj @@ -22,7 +22,7 @@ - + diff --git a/ManagedCode.Storage.AzureDataLake/AzureDataLakeStorage.cs b/ManagedCode.Storage.AzureDataLake/AzureDataLakeStorage.cs index 295ac028..b6d90ef5 100644 --- a/ManagedCode.Storage.AzureDataLake/AzureDataLakeStorage.cs +++ b/ManagedCode.Storage.AzureDataLake/AzureDataLakeStorage.cs @@ -245,12 +245,12 @@ protected override async Task DeleteDirectoryInternalAsync(string direct protected override Task SetLegalHoldInternalAsync(bool hasLegalHold, LegalHoldOptions options, CancellationToken cancellationToken = default) { - throw new NotSupportedException("Legal hold is not supported by Data Lake Storage"); + return Result.Fail(new NotSupportedException("Legal hold is not supported by Data Lake Storage")).AsTask(); } protected override Task> HasLegalHoldInternalAsync(LegalHoldOptions options, CancellationToken cancellationToken = default) { - throw new NotSupportedException("Legal hold is not supported by Data Lake Storage"); + return Result.Fail(new NotSupportedException("Legal hold is not supported by Data Lake Storage")).AsTask(); } private DataLakeFileClient GetFileClient(BaseOptions options) diff --git a/ManagedCode.Storage.AzureDataLake/ManagedCode.Storage.AzureDataLake.csproj b/ManagedCode.Storage.AzureDataLake/ManagedCode.Storage.AzureDataLake.csproj index 88167bf6..3af50248 100644 --- a/ManagedCode.Storage.AzureDataLake/ManagedCode.Storage.AzureDataLake.csproj +++ b/ManagedCode.Storage.AzureDataLake/ManagedCode.Storage.AzureDataLake.csproj @@ -22,7 +22,7 @@ - + diff --git a/ManagedCode.Storage.Core/ManagedCode.Storage.Core.csproj b/ManagedCode.Storage.Core/ManagedCode.Storage.Core.csproj index 0bc15c48..4e302a51 100644 --- a/ManagedCode.Storage.Core/ManagedCode.Storage.Core.csproj +++ b/ManagedCode.Storage.Core/ManagedCode.Storage.Core.csproj @@ -17,7 +17,7 @@ - + diff --git a/ManagedCode.Storage.FileSystem/FileSystemStorage.cs b/ManagedCode.Storage.FileSystem/FileSystemStorage.cs index 20f5dec8..5c043dfb 100644 --- a/ManagedCode.Storage.FileSystem/FileSystemStorage.cs +++ b/ManagedCode.Storage.FileSystem/FileSystemStorage.cs @@ -99,12 +99,9 @@ protected override async Task> DownloadInternalAsync(LocalFile var filePath = GetPathFromOptions(options); - if (File.Exists(filePath)) - { - return Result.Succeed(new LocalFile(filePath)); - } - - return Result.Fail(); + return File.Exists(filePath) + ? Result.Succeed(new LocalFile(filePath)) + : Result.Fail("File not found"); } protected override async Task> DeleteInternalAsync(DeleteOptions options, CancellationToken cancellationToken = default) @@ -135,20 +132,20 @@ protected override async Task> GetBlobMetadataInternalAsync var filePath = GetPathFromOptions(options); var fileInfo = new FileInfo(filePath); - if (fileInfo.Exists) + if (!fileInfo.Exists) { - var result = new BlobMetadata - { - Name = fileInfo.Name, - Uri = new Uri(Path.Combine(_path, filePath)), - MimeType = MimeHelper.GetMimeType(fileInfo.Extension), - Length = fileInfo.Length - }; - - return Result.Succeed(result); + return Result.Fail("File not found"); } - return Result.Fail(); + var result = new BlobMetadata + { + Name = fileInfo.Name, + Uri = new Uri(Path.Combine(_path, filePath)), + MimeType = MimeHelper.GetMimeType(fileInfo.Extension), + Length = fileInfo.Length + }; + + return Result.Succeed(result); } public override async IAsyncEnumerable GetBlobMetadataListAsync(string? directory = null, @@ -185,7 +182,7 @@ protected override async Task SetLegalHoldInternalAsync(bool hasLegalHol var file = await DownloadAsync(filePath, cancellationToken); if (file.IsError) - return Result.Fail(); + return Result.Fail(file.Error); var fileStream = File.OpenRead(file.Value!.FilePath); // Opening with FileAccess.Read only fileStream.Lock(0, fileStream.Length); // Attempting to lock a region of the read-only file @@ -196,7 +193,7 @@ protected override async Task SetLegalHoldInternalAsync(bool hasLegalHol } if (!hasLegalHold) - { + { if (_lockedFiles.ContainsKey(filePath)) { _lockedFiles[filePath].Unlock(0, _lockedFiles[filePath].Length); diff --git a/ManagedCode.Storage.FileSystem/ManagedCode.Storage.FileSystem.csproj b/ManagedCode.Storage.FileSystem/ManagedCode.Storage.FileSystem.csproj index 22115f73..35a43107 100644 --- a/ManagedCode.Storage.FileSystem/ManagedCode.Storage.FileSystem.csproj +++ b/ManagedCode.Storage.FileSystem/ManagedCode.Storage.FileSystem.csproj @@ -21,7 +21,7 @@ - + diff --git a/ManagedCode.Storage.Gcp/ManagedCode.Storage.Gcp.csproj b/ManagedCode.Storage.Gcp/ManagedCode.Storage.Gcp.csproj index 67fdeea9..3463e461 100644 --- a/ManagedCode.Storage.Gcp/ManagedCode.Storage.Gcp.csproj +++ b/ManagedCode.Storage.Gcp/ManagedCode.Storage.Gcp.csproj @@ -24,7 +24,7 @@ - + diff --git a/ManagedCode.Storage.Tests/ManagedCode.Storage.Tests.csproj b/ManagedCode.Storage.Tests/ManagedCode.Storage.Tests.csproj index 12d45d6e..cbca5ac5 100644 --- a/ManagedCode.Storage.Tests/ManagedCode.Storage.Tests.csproj +++ b/ManagedCode.Storage.Tests/ManagedCode.Storage.Tests.csproj @@ -22,7 +22,7 @@ - + From 59de3be6617eeb5533eaba27974323fcb60d35b0 Mon Sep 17 00:00:00 2001 From: dtymakhov Date: Wed, 27 Jul 2022 21:36:46 +0300 Subject: [PATCH 2/2] Updated readme and upgraded version --- Directory.Build.props | 4 +-- README.md | 62 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 89560932..5f4e9e67 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -13,8 +13,8 @@ MIT README.md Managed Code - Storage - 2.0.3 - 2.0.3 + 2.0.4 + 2.0.4 true diff --git a/README.md b/README.md index 94af0606..f4c1eb89 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ![img|300x200](https://raw.githubusercontent.com/managed-code-hub/Storage/main/logo.png) + # ManagedCode.Storage + [![.NET](https://github.com/managed-code-hub/Storage/actions/workflows/dotnet.yml/badge.svg)](https://github.com/managed-code-hub/Storage/actions/workflows/dotnet.yml) [![Coverage Status](https://coveralls.io/repos/github/managed-code-hub/Storage/badge.svg?branch=main&service=github)](https://coveralls.io/github/managed-code-hub/Storage?branch=main) [![nuget](https://github.com/managed-code-hub/Storage/actions/workflows/nuget.yml/badge.svg?branch=main)](https://github.com/managed-code-hub/Storage/actions/workflows/nuget.yml) @@ -16,16 +18,23 @@ # Storage --- + ## Storage pattern implementation for C#. + A universal storage for working with multiple storage providers: -- Azure + +- Azure - Google Cloud - Amazon - FileSystem -## General concept -The library incapsulates all provider specific to make connection and managing storages as easy as possible. You have as customer just connect the library in your Startup providing necessary connection strings and inject needed interfaces in your services. + +## General concept + +The library incapsulates all provider specific to make connection and managing storages as easy as possible. You have as customer just connect the +library in your Startup providing necessary connection strings and inject needed interfaces in your services. ## Connection modes + You can connect storage interface in two modes provider-specific and default. In case of default you are restricted with one storage type ### Azure @@ -82,11 +91,14 @@ public class MyService } } ``` +
Google Cloud (Click here to expand) -### Google Cloud +### Google Cloud + Default mode connection: + ```cs // Startup.cs services.AddGCPStorageAsDefault(opt => @@ -100,7 +112,9 @@ services.AddGCPStorageAsDefault(opt => }; }); ``` + Using in default mode: + ```cs // MyService.cs public class MyService @@ -113,7 +127,9 @@ public class MyService } } ``` + Provider-specific mode connection: + ```cs // Startup.cs services.AddGCPStorage(new GCPStorageOptions @@ -125,7 +141,9 @@ services.AddGCPStorage(new GCPStorageOptions } }); ``` + Using in provider-specific mode + ```cs // MyService.cs public class MyService @@ -137,13 +155,16 @@ public class MyService } } ``` +
Amazon (Click here to expand) - + ### Amazon + Default mode connection: + ```cs // Startup.cs //aws libarary overwrites property values. you should only create configurations this way. @@ -161,7 +182,9 @@ services.AddAWSStorageAsDefault(opt => opt.OriginalOptions = awsConfig; }); ``` + Using in default mode: + ```cs // MyService.cs public class MyService @@ -174,7 +197,9 @@ public class MyService } } ``` + Provider-specific mode connection: + ```cs // Startup.cs services.AddAWSStorage(new AWSStorageOptions @@ -185,7 +210,9 @@ services.AddAWSStorage(new AWSStorageOptions OriginalOptions = awsConfig }); ``` + Using in provider-specific mode + ```cs // MyService.cs public class MyService @@ -197,13 +224,16 @@ public class MyService } } ``` +
FileSystem (Click here to expand) - + ### FileSystem + Default mode connection: + ```cs // Startup.cs services.AddFileSystemStorageAsDefault(opt => @@ -211,7 +241,9 @@ services.AddFileSystemStorageAsDefault(opt => opt.BaseFolder = Path.Combine(Environment.CurrentDirectory, "{YOUR_BUCKET_NAME}"); }); ``` + Using in default mode: + ```cs // MyService.cs public class MyService @@ -224,7 +256,9 @@ public class MyService } } ``` + Provider-specific mode connection: + ```cs // Startup.cs services.AddFileSystemStorage(new FileSystemStorageOptions @@ -232,7 +266,9 @@ services.AddFileSystemStorage(new FileSystemStorageOptions BaseFolder = Path.Combine(Environment.CurrentDirectory, "{YOUR_BUCKET_NAME}"), }); ``` + Using in provider-specific mode + ```cs // MyService.cs public class MyService @@ -244,9 +280,11 @@ public class MyService } } ``` +
## How to use + We assume that below code snippets are placed in your service class with injected IStorage: ```cs @@ -261,6 +299,7 @@ public class MyService ``` ### Upload + ```cs await _storage.UploadAsync(new Stream()); await _storage.UploadAsync("some string content"); @@ -268,18 +307,29 @@ await _storage.UploadAsync(new FileInfo("D:\\my_report.txt")); ``` ### Delete + ```cs await _storage.DeleteAsync("my_report.txt"); ``` ### Download + ```cs var localFile = await _storage.DownloadAsync("my_report.txt"); ``` ### Get metadata + ```cs await _storage.GetBlobMetadataAsync("my_report.txt"); ``` +### Native client + +If you need more flexibility, you can use native client for any IStorage<T> + +```cs +_storage.StorageClient +``` +