From fffa9f92376a964d58e03cc60e079c4b37fd3783 Mon Sep 17 00:00:00 2001
From: maliming <6908465+maliming@users.noreply.github.com>
Date: Wed, 3 Jun 2020 15:11:33 +0800
Subject: [PATCH 1/8] Add Volo.Abp.BlobStoring.Azure project.
---
framework/Volo.Abp.sln | 7 +++++
.../FodyWeavers.xml | 3 ++
.../FodyWeavers.xsd | 30 +++++++++++++++++++
.../Volo.Abp.BlobStoring.Azure.csproj | 21 +++++++++++++
.../Azure/AbpBlobStoringAzureModule.cs | 12 ++++++++
...ureBlobContainerConfigurationExtensions.cs | 24 +++++++++++++++
.../BlobStoring/Azure/AzureBlobProvider.cs | 29 ++++++++++++++++++
.../Azure/AzureBlobProviderConfiguration.cs | 12 ++++++++
.../AzureBlobProviderConfigurationNames.cs | 8 +++++
9 files changed, 146 insertions(+)
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/FodyWeavers.xml
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/FodyWeavers.xsd
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureModule.cs
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobContainerConfigurationExtensions.cs
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index 135afaf4d9..d488b3d5b0 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -301,6 +301,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlobStoring.FileSy
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EntityFrameworkCore.Oracle.Devart", "src\Volo.Abp.EntityFrameworkCore.Oracle.Devart\Volo.Abp.EntityFrameworkCore.Oracle.Devart.csproj", "{75E5C841-5F36-4C44-A532-57CB8E7FFE15}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlobStoring.Azure", "src\Volo.Abp.BlobStoring.Azure\Volo.Abp.BlobStoring.Azure.csproj", "{C44242F7-D55D-4867-AAF4-A786E404312E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -895,6 +897,10 @@ Global
{75E5C841-5F36-4C44-A532-57CB8E7FFE15}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75E5C841-5F36-4C44-A532-57CB8E7FFE15}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75E5C841-5F36-4C44-A532-57CB8E7FFE15}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C44242F7-D55D-4867-AAF4-A786E404312E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C44242F7-D55D-4867-AAF4-A786E404312E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C44242F7-D55D-4867-AAF4-A786E404312E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C44242F7-D55D-4867-AAF4-A786E404312E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1047,6 +1053,7 @@ Global
{02B1FBE2-850E-4612-ABC6-DD62BCF2DD6B} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{68443D4A-1608-4039-B995-7AF4CF82E9F8} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{75E5C841-5F36-4C44-A532-57CB8E7FFE15} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {C44242F7-D55D-4867-AAF4-A786E404312E} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/FodyWeavers.xml b/framework/src/Volo.Abp.BlobStoring.Azure/FodyWeavers.xml
new file mode 100644
index 0000000000..bc5a74a236
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/FodyWeavers.xsd b/framework/src/Volo.Abp.BlobStoring.Azure/FodyWeavers.xsd
new file mode 100644
index 0000000000..3f3946e282
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj b/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj
new file mode 100644
index 0000000000..f7e004cfc8
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ netstandard2.0
+ Volo.Abp.BlobStoring.Azure
+ Volo.Abp.BlobStoring.Azure
+ $(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
+ false
+ false
+ false
+
+
+
+
+
+
+
+
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureModule.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureModule.cs
new file mode 100644
index 0000000000..a7a935abf5
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureModule.cs
@@ -0,0 +1,12 @@
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.BlobStoring.Azure
+{
+ [DependsOn(
+ typeof(AbpBlobStoringModule)
+ )]
+ public class AbpBlobStoringAzureModule : AbpModule
+ {
+
+ }
+}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobContainerConfigurationExtensions.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobContainerConfigurationExtensions.cs
new file mode 100644
index 0000000000..917870aa9d
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobContainerConfigurationExtensions.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public static class AzureBlobContainerConfigurationExtensions
+ {
+ public static AzureBlobProviderConfiguration GetAzureConfiguration(
+ this BlobContainerConfiguration containerConfiguration)
+ {
+ return new AzureBlobProviderConfiguration(containerConfiguration);
+ }
+
+ public static BlobContainerConfiguration UseAzure(
+ this BlobContainerConfiguration containerConfiguration,
+ Action fileSystemConfigureAction)
+ {
+ containerConfiguration.ProviderType = typeof(AzureBlobProvider);
+
+ fileSystemConfigureAction(new AzureBlobProviderConfiguration(containerConfiguration));
+
+ return containerConfiguration;
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
new file mode 100644
index 0000000000..895fa5c72f
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
@@ -0,0 +1,29 @@
+using System.IO;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public class AzureBlobProvider : BlobProviderBase, ITransientDependency
+ {
+ public override Task SaveAsync(BlobProviderSaveArgs args)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override Task DeleteAsync(BlobProviderDeleteArgs args)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override Task ExistsAsync(BlobProviderExistsArgs args)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override Task GetOrNullAsync(BlobProviderGetArgs args)
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
new file mode 100644
index 0000000000..53352661f9
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
@@ -0,0 +1,12 @@
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public class AzureBlobProviderConfiguration
+ {
+ private readonly BlobContainerConfiguration _containerConfiguration;
+
+ public AzureBlobProviderConfiguration(BlobContainerConfiguration containerConfiguration)
+ {
+ _containerConfiguration = containerConfiguration;
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
new file mode 100644
index 0000000000..8452b0531f
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
@@ -0,0 +1,8 @@
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public class AzureBlobProviderConfigurationNames
+ {
+
+
+ }
+}
From 44521a6bd30ba1e6385ab79017665ffa93c40d1a Mon Sep 17 00:00:00 2001
From: maliming <6908465+maliming@users.noreply.github.com>
Date: Wed, 3 Jun 2020 18:25:38 +0800
Subject: [PATCH 2/8] Implement azure blob storage.
---
framework/Volo.Abp.sln | 7 +++
.../Volo.Abp.BlobStoring.Azure.csproj | 1 +
.../BlobStoring/Azure/AzureBlobProvider.cs | 59 ++++++++++++++++---
.../Azure/AzureBlobProviderConfiguration.cs | 12 ++++
.../AzureBlobProviderConfigurationNames.cs | 6 +-
.../Volo/Abp/BlobStoring/BlobProviderArgs.cs | 2 +-
.../System/IO/AbpStreamExtensions.cs | 3 +
.../Volo.Abp.BlobStoring.Azure.Tests.csproj | 19 ++++++
.../Azure/AbpBlobStoringAzureTestBase.cs | 12 ++++
.../Azure/AbpBlobStoringAzureTestModule.cs | 49 +++++++++++++++
.../Azure/AzureBlobContainer_Tests.cs | 12 ++++
11 files changed, 170 insertions(+), 12 deletions(-)
create mode 100644 framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo.Abp.BlobStoring.Azure.Tests.csproj
create mode 100644 framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestBase.cs
create mode 100644 framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
create mode 100644 framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index d488b3d5b0..e02d40b1e0 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -303,6 +303,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EntityFrameworkCor
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlobStoring.Azure", "src\Volo.Abp.BlobStoring.Azure\Volo.Abp.BlobStoring.Azure.csproj", "{C44242F7-D55D-4867-AAF4-A786E404312E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlobStoring.Azure.Tests", "test\Volo.Abp.BlobStoring.Azure.Tests\Volo.Abp.BlobStoring.Azure.Tests.csproj", "{A80E9A0B-8932-4B5D-83FB-6751708FD484}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -901,6 +903,10 @@ Global
{C44242F7-D55D-4867-AAF4-A786E404312E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C44242F7-D55D-4867-AAF4-A786E404312E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C44242F7-D55D-4867-AAF4-A786E404312E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A80E9A0B-8932-4B5D-83FB-6751708FD484}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A80E9A0B-8932-4B5D-83FB-6751708FD484}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A80E9A0B-8932-4B5D-83FB-6751708FD484}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A80E9A0B-8932-4B5D-83FB-6751708FD484}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1054,6 +1060,7 @@ Global
{68443D4A-1608-4039-B995-7AF4CF82E9F8} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{75E5C841-5F36-4C44-A532-57CB8E7FFE15} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{C44242F7-D55D-4867-AAF4-A786E404312E} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {A80E9A0B-8932-4B5D-83FB-6751708FD484} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj b/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj
index f7e004cfc8..1e7c51f4fc 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj
@@ -16,6 +16,7 @@
+
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
index 895fa5c72f..d43fbb2158 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
@@ -1,29 +1,72 @@
using System.IO;
using System.Threading.Tasks;
+using Azure.Storage.Blobs;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BlobStoring.Azure
{
public class AzureBlobProvider : BlobProviderBase, ITransientDependency
{
- public override Task SaveAsync(BlobProviderSaveArgs args)
+ public override async Task SaveAsync(BlobProviderSaveArgs args)
{
- throw new System.NotImplementedException();
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), args.BlobName);
+
+ if (!args.OverrideExisting && await BlobExistsAsync(blobClient))
+ {
+ throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{args.ContainerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
+ }
+
+ await blobClient.UploadAsync(args.BlobStream, true);
+ }
+
+ public override async Task DeleteAsync(BlobProviderDeleteArgs args)
+ {
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), args.BlobName);
+ if (await BlobExistsAsync(blobClient))
+ {
+ return (await blobClient.DeleteAsync()).Status == 200;
+ }
+
+ return false;
+ }
+
+ public override async Task ExistsAsync(BlobProviderExistsArgs args)
+ {
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), args.BlobName);
+ return await BlobExistsAsync(blobClient);
+ }
+
+ public override async Task GetOrNullAsync(BlobProviderGetArgs args)
+ {
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), args.BlobName);
+ if (!await BlobExistsAsync(blobClient))
+ {
+ return null;
+ }
+
+ var download = await blobClient.DownloadAsync();
+
+ var memoryStream = new MemoryStream();
+ await download.Value.Content.CopyToAsync(memoryStream);
+ return memoryStream;
}
- public override Task DeleteAsync(BlobProviderDeleteArgs args)
+ protected virtual BlobClient GetBlobClient(AzureBlobProviderConfiguration configuration, string blobName)
{
- throw new System.NotImplementedException();
+ var blobContainerClient = GetBlobContainerClient(configuration);
+ return blobContainerClient.GetBlobClient(blobName);
}
- public override Task ExistsAsync(BlobProviderExistsArgs args)
+ protected virtual BlobContainerClient GetBlobContainerClient(AzureBlobProviderConfiguration configuration)
{
- throw new System.NotImplementedException();
+ var blobServiceClient = new BlobServiceClient(configuration.ConnectionString);
+ return blobServiceClient.GetBlobContainerClient(configuration.ContainerName);
}
- public override Task GetOrNullAsync(BlobProviderGetArgs args)
+ private static async Task BlobExistsAsync(BlobClient blobClient)
{
- throw new System.NotImplementedException();
+ var response = await blobClient.ExistsAsync();
+ return response.Value;
}
}
}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
index 53352661f9..67f6eca307 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
@@ -2,6 +2,18 @@
{
public class AzureBlobProviderConfiguration
{
+ public string ConnectionString
+ {
+ get => _containerConfiguration.GetConfiguration(AzureBlobProviderConfigurationNames.ConnectionString);
+ set => _containerConfiguration.SetConfiguration(AzureBlobProviderConfigurationNames.ConnectionString, Check.NotNullOrWhiteSpace(value, nameof(value)));
+ }
+
+ public string ContainerName
+ {
+ get => _containerConfiguration.GetConfiguration(AzureBlobProviderConfigurationNames.ContainerName);
+ set => _containerConfiguration.SetConfiguration(AzureBlobProviderConfigurationNames.ContainerName, Check.NotNullOrWhiteSpace(value, nameof(value)));
+ }
+
private readonly BlobContainerConfiguration _containerConfiguration;
public AzureBlobProviderConfiguration(BlobContainerConfiguration containerConfiguration)
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
index 8452b0531f..f90f037046 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
@@ -1,8 +1,8 @@
namespace Volo.Abp.BlobStoring.Azure
{
- public class AzureBlobProviderConfigurationNames
+ public static class AzureBlobProviderConfigurationNames
{
-
-
+ public const string ConnectionString = "Azure.ConnectionString";
+ public const string ContainerName = "Azure.ContainerName";
}
}
diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderArgs.cs
index fcc264977a..0170409a16 100644
--- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderArgs.cs
+++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderArgs.cs
@@ -28,4 +28,4 @@ namespace Volo.Abp.BlobStoring
CancellationToken = cancellationToken;
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs b/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs
index 466d73b2a7..bd85773a9b 100644
--- a/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs
+++ b/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs
@@ -9,6 +9,7 @@ namespace System.IO
{
using (var memoryStream = new MemoryStream())
{
+ stream.Position = 0;
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
@@ -18,6 +19,7 @@ namespace System.IO
{
using (var memoryStream = new MemoryStream())
{
+ stream.Position = 0;
await stream.CopyToAsync(memoryStream, cancellationToken);
return memoryStream.ToArray();
}
@@ -25,6 +27,7 @@ namespace System.IO
public static Task CopyToAsync(this Stream stream, Stream destination, CancellationToken cancellationToken)
{
+ stream.Position = 0;
return stream.CopyToAsync(
destination,
81920, //this is already the default value, but needed to set to be able to pass the cancellationToken
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo.Abp.BlobStoring.Azure.Tests.csproj b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo.Abp.BlobStoring.Azure.Tests.csproj
new file mode 100644
index 0000000000..ff97ea97d3
--- /dev/null
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo.Abp.BlobStoring.Azure.Tests.csproj
@@ -0,0 +1,19 @@
+
+
+
+
+
+ netcoreapp3.1
+
+ 9f0d2c00-80c1-435b-bfab-2c39c8249091
+
+
+
+
+
+
+
+
+
+
+
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestBase.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestBase.cs
new file mode 100644
index 0000000000..7213c8eb78
--- /dev/null
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestBase.cs
@@ -0,0 +1,12 @@
+using Volo.Abp.Testing;
+
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public class AbpBlobStoringAzureTestBase : AbpIntegratedTest
+ {
+ protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
+ {
+ options.UseAutofac();
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
new file mode 100644
index 0000000000..354b8b93b6
--- /dev/null
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
@@ -0,0 +1,49 @@
+using System;
+using Azure.Storage.Blobs;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.BlobStoring.Azure
+{
+ [DependsOn(
+ typeof(AbpBlobStoringAzureModule),
+ typeof(AbpBlobStoringTestModule)
+ )]
+ public class AbpBlobStoringAzureTestModule : AbpModule
+ {
+ private readonly string _randomContainerName = "abp-azure-test-container-" + Guid.NewGuid().ToString("N");
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.ReplaceConfiguration(ConfigurationHelper.BuildConfiguration(builderAction: builder =>
+ {
+ builder.AddUserSecrets("9f0d2c00-80c1-435b-bfab-2c39c8249091");
+ }));
+
+ var configuration = context.Services.GetConfiguration();
+
+ var blobServiceClient = new BlobServiceClient(configuration["Azure:ConnectionString"]);
+ blobServiceClient.CreateBlobContainer(_randomContainerName);
+
+ Configure(options =>
+ {
+ options.Containers.ConfigureAll((containerName, containerConfiguration) =>
+ {
+ containerConfiguration.UseAzure(azure =>
+ {
+ azure.ConnectionString = configuration["Azure:ConnectionString"];
+ azure.ContainerName = _randomContainerName;
+ });
+ });
+ });
+ }
+
+ public override void OnApplicationShutdown(ApplicationShutdownContext context)
+ {
+ var configuration = context.ServiceProvider.GetRequiredService();
+ var blobServiceClient = new BlobServiceClient(configuration["Azure:ConnectionString"]);
+ blobServiceClient.DeleteBlobContainer(_randomContainerName);
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
new file mode 100644
index 0000000000..f4e820d46f
--- /dev/null
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
@@ -0,0 +1,12 @@
+using Xunit;
+
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public class AzureBlobContainer_Tests : BlobContainer_Tests
+ {
+ public AzureBlobContainer_Tests()
+ {
+
+ }
+ }
+}
From 0e2e5629aa9370c5f548fdacf1bcba1d4c70f17e Mon Sep 17 00:00:00 2001
From: maliming <6908465+maliming@users.noreply.github.com>
Date: Wed, 3 Jun 2020 18:44:39 +0800
Subject: [PATCH 3/8] Skip azure unit testing.
---
.../Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs | 4 +++-
.../Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs | 3 +++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
index 354b8b93b6..4a1b0f8114 100644
--- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
@@ -12,13 +12,15 @@ namespace Volo.Abp.BlobStoring.Azure
)]
public class AbpBlobStoringAzureTestModule : AbpModule
{
+ public static string UserSecretsId = "9f0d2c00-80c1-435b-bfab-2c39c8249091";
+
private readonly string _randomContainerName = "abp-azure-test-container-" + Guid.NewGuid().ToString("N");
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.ReplaceConfiguration(ConfigurationHelper.BuildConfiguration(builderAction: builder =>
{
- builder.AddUserSecrets("9f0d2c00-80c1-435b-bfab-2c39c8249091");
+ builder.AddUserSecrets(UserSecretsId);
}));
var configuration = context.Services.GetConfiguration();
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
index f4e820d46f..75070d2cac 100644
--- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
@@ -1,7 +1,9 @@
using Xunit;
+//#define I_HAVE_SET_THE_CORRECT_CONNECTIONSTRING_IN_THE_USERSECRETS_FILE
namespace Volo.Abp.BlobStoring.Azure
{
+#if I_HAVE_SET_THE_CORRECT_CONNECTION_STRING_IN_THE_USERSECRETS_FILE
public class AzureBlobContainer_Tests : BlobContainer_Tests
{
public AzureBlobContainer_Tests()
@@ -9,4 +11,5 @@ namespace Volo.Abp.BlobStoring.Azure
}
}
+#endif
}
From 3acc5c8c85eb3c60a56d6bf01ed018e8abf8cfb4 Mon Sep 17 00:00:00 2001
From: maliming <6908465+maliming@users.noreply.github.com>
Date: Wed, 3 Jun 2020 19:05:23 +0800
Subject: [PATCH 4/8] Small refactoring.
---
.../BlobStoring/Azure/AbpBlobStoringAzureModule.cs | 4 +---
.../Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs | 4 +---
.../Azure/AbpBlobStoringAzureTestModule.cs | 12 ++++++++----
.../BlobStoring/Azure/AzureBlobContainer_Tests.cs | 7 ++++---
4 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureModule.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureModule.cs
index a7a935abf5..0b386fbec1 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureModule.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureModule.cs
@@ -2,9 +2,7 @@
namespace Volo.Abp.BlobStoring.Azure
{
- [DependsOn(
- typeof(AbpBlobStoringModule)
- )]
+ [DependsOn(typeof(AbpBlobStoringModule))]
public class AbpBlobStoringAzureModule : AbpModule
{
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
index d43fbb2158..eb69bb802a 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
@@ -45,7 +45,6 @@ namespace Volo.Abp.BlobStoring.Azure
}
var download = await blobClient.DownloadAsync();
-
var memoryStream = new MemoryStream();
await download.Value.Content.CopyToAsync(memoryStream);
return memoryStream;
@@ -65,8 +64,7 @@ namespace Volo.Abp.BlobStoring.Azure
private static async Task BlobExistsAsync(BlobClient blobClient)
{
- var response = await blobClient.ExistsAsync();
- return response.Value;
+ return (await blobClient.ExistsAsync()).Value;
}
}
}
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
index 4a1b0f8114..4711699726 100644
--- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
@@ -12,7 +12,9 @@ namespace Volo.Abp.BlobStoring.Azure
)]
public class AbpBlobStoringAzureTestModule : AbpModule
{
- public static string UserSecretsId = "9f0d2c00-80c1-435b-bfab-2c39c8249091";
+ private const string UserSecretsId = "9f0d2c00-80c1-435b-bfab-2c39c8249091";
+
+ private string _connectionString;
private readonly string _randomContainerName = "abp-azure-test-container-" + Guid.NewGuid().ToString("N");
@@ -25,7 +27,9 @@ namespace Volo.Abp.BlobStoring.Azure
var configuration = context.Services.GetConfiguration();
- var blobServiceClient = new BlobServiceClient(configuration["Azure:ConnectionString"]);
+ _connectionString = configuration["Azure:ConnectionString"];
+
+ var blobServiceClient = new BlobServiceClient(_connectionString);
blobServiceClient.CreateBlobContainer(_randomContainerName);
Configure(options =>
@@ -34,7 +38,7 @@ namespace Volo.Abp.BlobStoring.Azure
{
containerConfiguration.UseAzure(azure =>
{
- azure.ConnectionString = configuration["Azure:ConnectionString"];
+ azure.ConnectionString = _connectionString;
azure.ContainerName = _randomContainerName;
});
});
@@ -44,7 +48,7 @@ namespace Volo.Abp.BlobStoring.Azure
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
var configuration = context.ServiceProvider.GetRequiredService();
- var blobServiceClient = new BlobServiceClient(configuration["Azure:ConnectionString"]);
+ var blobServiceClient = new BlobServiceClient(_connectionString);
blobServiceClient.DeleteBlobContainer(_randomContainerName);
}
}
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
index 75070d2cac..751918be85 100644
--- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobContainer_Tests.cs
@@ -1,9 +1,10 @@
using Xunit;
-//#define I_HAVE_SET_THE_CORRECT_CONNECTIONSTRING_IN_THE_USERSECRETS_FILE
namespace Volo.Abp.BlobStoring.Azure
{
-#if I_HAVE_SET_THE_CORRECT_CONNECTION_STRING_IN_THE_USERSECRETS_FILE
+ /*
+ //Please set the correct connection string in secrets.json and continue the test.
+
public class AzureBlobContainer_Tests : BlobContainer_Tests
{
public AzureBlobContainer_Tests()
@@ -11,5 +12,5 @@ namespace Volo.Abp.BlobStoring.Azure
}
}
-#endif
+ */
}
From 057c4c1a250c3d14471ef87a6b9b9db1ce04b46f Mon Sep 17 00:00:00 2001
From: maliming <6908465+maliming@users.noreply.github.com>
Date: Thu, 4 Jun 2020 15:35:43 +0800
Subject: [PATCH 5/8] Compatible with multi-tenancy.
---
...ureBlobContainerConfigurationExtensions.cs | 4 +-
.../BlobStoring/Azure/AzureBlobProvider.cs | 29 ++++++----
.../Azure/DefaultAzureBlobNameCalculator.cs | 22 +++++++
.../Azure/IAzureBlobNameCalculator.cs | 7 +++
.../Azure/AbpBlobStoringAzureTestBase.cs | 8 +++
.../Azure/AbpBlobStoringAzureTestModule.cs | 14 ++++-
.../Azure/AzureBlobNameCalculator_Tests.cs | 57 +++++++++++++++++++
7 files changed, 127 insertions(+), 14 deletions(-)
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/DefaultAzureBlobNameCalculator.cs
create mode 100644 framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/IAzureBlobNameCalculator.cs
create mode 100644 framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobNameCalculator_Tests.cs
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobContainerConfigurationExtensions.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobContainerConfigurationExtensions.cs
index 917870aa9d..945c930175 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobContainerConfigurationExtensions.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobContainerConfigurationExtensions.cs
@@ -12,11 +12,11 @@ namespace Volo.Abp.BlobStoring.Azure
public static BlobContainerConfiguration UseAzure(
this BlobContainerConfiguration containerConfiguration,
- Action fileSystemConfigureAction)
+ Action azureConfigureAction)
{
containerConfiguration.ProviderType = typeof(AzureBlobProvider);
- fileSystemConfigureAction(new AzureBlobProviderConfiguration(containerConfiguration));
+ azureConfigureAction(new AzureBlobProviderConfiguration(containerConfiguration));
return containerConfiguration;
}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
index eb69bb802a..e0b70dc66c 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
@@ -1,15 +1,24 @@
using System.IO;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Specialized;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BlobStoring.Azure
{
public class AzureBlobProvider : BlobProviderBase, ITransientDependency
{
+ protected IAzureBlobNameCalculator AzureBlobNameCalculator { get; }
+
+ public AzureBlobProvider(IAzureBlobNameCalculator azureBlobNameCalculator)
+ {
+ AzureBlobNameCalculator = azureBlobNameCalculator;
+ }
+
public override async Task SaveAsync(BlobProviderSaveArgs args)
{
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), args.BlobName);
+ var blobName = AzureBlobNameCalculator.Calculate(args);
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
if (!args.OverrideExisting && await BlobExistsAsync(blobClient))
{
@@ -21,24 +30,22 @@ namespace Volo.Abp.BlobStoring.Azure
public override async Task DeleteAsync(BlobProviderDeleteArgs args)
{
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), args.BlobName);
- if (await BlobExistsAsync(blobClient))
- {
- return (await blobClient.DeleteAsync()).Status == 200;
- }
-
- return false;
+ var blobName = AzureBlobNameCalculator.Calculate(args);
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
+ return await blobClient.DeleteIfExistsAsync();
}
public override async Task ExistsAsync(BlobProviderExistsArgs args)
{
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), args.BlobName);
+ var blobName = AzureBlobNameCalculator.Calculate(args);
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
return await BlobExistsAsync(blobClient);
}
public override async Task GetOrNullAsync(BlobProviderGetArgs args)
{
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), args.BlobName);
+ var blobName = AzureBlobNameCalculator.Calculate(args);
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
if (!await BlobExistsAsync(blobClient))
{
return null;
@@ -62,7 +69,7 @@ namespace Volo.Abp.BlobStoring.Azure
return blobServiceClient.GetBlobContainerClient(configuration.ContainerName);
}
- private static async Task BlobExistsAsync(BlobClient blobClient)
+ private static async Task BlobExistsAsync(BlobBaseClient blobClient)
{
return (await blobClient.ExistsAsync()).Value;
}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/DefaultAzureBlobNameCalculator.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/DefaultAzureBlobNameCalculator.cs
new file mode 100644
index 0000000000..0c6cd481c9
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/DefaultAzureBlobNameCalculator.cs
@@ -0,0 +1,22 @@
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.MultiTenancy;
+
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public class DefaultAzureBlobNameCalculator : IAzureBlobNameCalculator, ITransientDependency
+ {
+ protected ICurrentTenant CurrentTenant { get; }
+
+ public DefaultAzureBlobNameCalculator(ICurrentTenant currentTenant)
+ {
+ CurrentTenant = currentTenant;
+ }
+
+ public virtual string Calculate(BlobProviderArgs args)
+ {
+ return CurrentTenant.Id == null
+ ? $"host/{args.BlobName}"
+ : $"tenants/{CurrentTenant.Id.Value.ToString("D")}/{args.BlobName}";
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/IAzureBlobNameCalculator.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/IAzureBlobNameCalculator.cs
new file mode 100644
index 0000000000..5985a9278d
--- /dev/null
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/IAzureBlobNameCalculator.cs
@@ -0,0 +1,7 @@
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public interface IAzureBlobNameCalculator
+ {
+ string Calculate(BlobProviderArgs args);
+ }
+}
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestBase.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestBase.cs
index 7213c8eb78..8941234cbf 100644
--- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestBase.cs
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestBase.cs
@@ -2,6 +2,14 @@
namespace Volo.Abp.BlobStoring.Azure
{
+ public class AbpBlobStoringAzureTestCommonBase : AbpIntegratedTest
+ {
+ protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
+ {
+ options.UseAutofac();
+ }
+ }
+
public class AbpBlobStoringAzureTestBase : AbpIntegratedTest
{
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
index 4711699726..a45d209b32 100644
--- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
@@ -6,10 +6,22 @@ using Volo.Abp.Modularity;
namespace Volo.Abp.BlobStoring.Azure
{
+
+ ///
+ /// This module will not try to connect to azure.
+ ///
[DependsOn(
typeof(AbpBlobStoringAzureModule),
typeof(AbpBlobStoringTestModule)
)]
+ public class AbpBlobStoringAzureTestCommonModule : AbpModule
+ {
+
+ }
+
+ [DependsOn(
+ typeof(AbpBlobStoringAzureTestCommonModule)
+ )]
public class AbpBlobStoringAzureTestModule : AbpModule
{
private const string UserSecretsId = "9f0d2c00-80c1-435b-bfab-2c39c8249091";
@@ -47,9 +59,9 @@ namespace Volo.Abp.BlobStoring.Azure
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
- var configuration = context.ServiceProvider.GetRequiredService();
var blobServiceClient = new BlobServiceClient(_connectionString);
blobServiceClient.DeleteBlobContainer(_randomContainerName);
}
}
+
}
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobNameCalculator_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobNameCalculator_Tests.cs
new file mode 100644
index 0000000000..4540d208ae
--- /dev/null
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AzureBlobNameCalculator_Tests.cs
@@ -0,0 +1,57 @@
+using System;
+using Shouldly;
+using Volo.Abp.MultiTenancy;
+using Xunit;
+
+namespace Volo.Abp.BlobStoring.Azure
+{
+ public class AzureBlobNameCalculator_Tests : AbpBlobStoringAzureTestCommonBase
+ {
+ private readonly IAzureBlobNameCalculator _calculator;
+ private readonly ICurrentTenant _currentTenant;
+
+ private const string AzureContainerName = "/";
+ private const string AzureSeparator = "/";
+
+ public AzureBlobNameCalculator_Tests()
+ {
+ _calculator = GetRequiredService();
+ _currentTenant = GetRequiredService();
+ }
+
+ [Fact]
+ public void Default_Settings()
+ {
+ _calculator.Calculate(
+ GetArgs("my-container", "my-blob")
+ ).ShouldBe($"host{AzureSeparator}my-blob");
+ }
+
+ [Fact]
+ public void Default_Settings_With_TenantId()
+ {
+ var tenantId = Guid.NewGuid();
+
+ using (_currentTenant.Change(tenantId))
+ {
+ _calculator.Calculate(
+ GetArgs("my-container", "my-blob")
+ ).ShouldBe($"tenants{AzureSeparator}{tenantId:D}{AzureSeparator}my-blob");
+ }
+ }
+
+ private static BlobProviderArgs GetArgs(
+ string containerName,
+ string blobName)
+ {
+ return new BlobProviderGetArgs(
+ containerName,
+ new BlobContainerConfiguration().UseAzure(x =>
+ {
+ x.ContainerName = containerName;
+ }),
+ blobName
+ );
+ }
+ }
+}
From 3932ea3709a8a404ba365fe617492da39b9c2a08 Mon Sep 17 00:00:00 2001
From: maliming <6908465+maliming@users.noreply.github.com>
Date: Fri, 5 Jun 2020 18:37:56 +0800
Subject: [PATCH 6/8] Support CreateContainerIfNotExists.
---
.../BlobStoring/Azure/AzureBlobProvider.cs | 45 ++++++++++++++-----
.../Azure/AzureBlobProviderConfiguration.cs | 9 ++++
.../AzureBlobProviderConfigurationNames.cs | 1 +
.../Azure/AbpBlobStoringAzureTestModule.cs | 7 +--
4 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
index e0b70dc66c..ec854b7be3 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
@@ -18,39 +18,49 @@ namespace Volo.Abp.BlobStoring.Azure
public override async Task SaveAsync(BlobProviderSaveArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
+ var configuration = args.Configuration.GetAzureConfiguration();
- if (!args.OverrideExisting && await BlobExistsAsync(blobClient))
+ if (!args.OverrideExisting && await BlobExistsAsync(configuration, blobName))
{
throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{args.ContainerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
}
- await blobClient.UploadAsync(args.BlobStream, true);
+ if (configuration.CreateContainerIfNotExists)
+ {
+ await CreateContainerIfNotExists(args.Configuration.GetAzureConfiguration());
+ }
+
+ await GetBlobClient(configuration, blobName).UploadAsync(args.BlobStream, true);
}
public override async Task DeleteAsync(BlobProviderDeleteArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
- return await blobClient.DeleteIfExistsAsync();
+
+ if (await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName))
+ {
+ return await GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName).DeleteIfExistsAsync();
+ }
+
+ return false;
}
public override async Task ExistsAsync(BlobProviderExistsArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
- return await BlobExistsAsync(blobClient);
+ return await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName);
}
public override async Task GetOrNullAsync(BlobProviderGetArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
- if (!await BlobExistsAsync(blobClient))
+
+ if (!await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName))
{
return null;
}
+ var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
var download = await blobClient.DownloadAsync();
var memoryStream = new MemoryStream();
await download.Value.Content.CopyToAsync(memoryStream);
@@ -69,9 +79,22 @@ namespace Volo.Abp.BlobStoring.Azure
return blobServiceClient.GetBlobContainerClient(configuration.ContainerName);
}
- private static async Task BlobExistsAsync(BlobBaseClient blobClient)
+ protected virtual async Task CreateContainerIfNotExists(AzureBlobProviderConfiguration configuration)
+ {
+ var blobContainerClient = GetBlobContainerClient(configuration);
+ await blobContainerClient.CreateIfNotExistsAsync();
+ }
+
+ private async Task BlobExistsAsync(AzureBlobProviderConfiguration configuration, string blobName)
+ {
+ // Make sure Blob Container exists.
+ return await ContainerExistsAsync(GetBlobContainerClient(configuration)) &&
+ (await GetBlobClient(configuration, blobName).ExistsAsync()).Value;
+ }
+
+ private static async Task ContainerExistsAsync(BlobContainerClient blobContainerClient)
{
- return (await blobClient.ExistsAsync()).Value;
+ return (await blobContainerClient.ExistsAsync()).Value;
}
}
}
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
index 67f6eca307..a0906ed31f 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
@@ -14,6 +14,15 @@
set => _containerConfiguration.SetConfiguration(AzureBlobProviderConfigurationNames.ContainerName, Check.NotNullOrWhiteSpace(value, nameof(value)));
}
+ ///
+ /// Default value: false.
+ ///
+ public bool CreateContainerIfNotExists
+ {
+ get => _containerConfiguration.GetConfigurationOrDefault(AzureBlobProviderConfigurationNames.CreateContainerIfNotExists, false);
+ set => _containerConfiguration.SetConfiguration(AzureBlobProviderConfigurationNames.CreateContainerIfNotExists, value);
+ }
+
private readonly BlobContainerConfiguration _containerConfiguration;
public AzureBlobProviderConfiguration(BlobContainerConfiguration containerConfiguration)
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
index f90f037046..b8fbff19d2 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs
@@ -4,5 +4,6 @@
{
public const string ConnectionString = "Azure.ConnectionString";
public const string ContainerName = "Azure.ContainerName";
+ public const string CreateContainerIfNotExists = "Azure.CreateContainerIfNotExists";
}
}
diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
index a45d209b32..5e66be4e19 100644
--- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
+++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs
@@ -38,12 +38,8 @@ namespace Volo.Abp.BlobStoring.Azure
}));
var configuration = context.Services.GetConfiguration();
-
_connectionString = configuration["Azure:ConnectionString"];
- var blobServiceClient = new BlobServiceClient(_connectionString);
- blobServiceClient.CreateBlobContainer(_randomContainerName);
-
Configure(options =>
{
options.Containers.ConfigureAll((containerName, containerConfiguration) =>
@@ -52,6 +48,7 @@ namespace Volo.Abp.BlobStoring.Azure
{
azure.ConnectionString = _connectionString;
azure.ContainerName = _randomContainerName;
+ azure.CreateContainerIfNotExists = true;
});
});
});
@@ -60,7 +57,7 @@ namespace Volo.Abp.BlobStoring.Azure
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
var blobServiceClient = new BlobServiceClient(_connectionString);
- blobServiceClient.DeleteBlobContainer(_randomContainerName);
+ blobServiceClient.GetBlobContainerClient(_randomContainerName).DeleteIfExists();
}
}
From f1f3413274eb0eea8c32e8b891182e1a638fb050 Mon Sep 17 00:00:00 2001
From: maliming <6908465+maliming@users.noreply.github.com>
Date: Wed, 10 Jun 2020 11:20:18 +0800
Subject: [PATCH 7/8] Reuse azure configuration.
---
.../Abp/BlobStoring/Azure/AzureBlobProvider.cs | 18 +++++++++++-------
.../Azure/AzureBlobProviderConfiguration.cs | 5 +++++
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
index ec854b7be3..af5150c0a9 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
@@ -22,12 +22,12 @@ namespace Volo.Abp.BlobStoring.Azure
if (!args.OverrideExisting && await BlobExistsAsync(configuration, blobName))
{
- throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{args.ContainerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
+ throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{configuration.ContainerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
}
if (configuration.CreateContainerIfNotExists)
{
- await CreateContainerIfNotExists(args.Configuration.GetAzureConfiguration());
+ await CreateContainerIfNotExists(configuration);
}
await GetBlobClient(configuration, blobName).UploadAsync(args.BlobStream, true);
@@ -36,10 +36,11 @@ namespace Volo.Abp.BlobStoring.Azure
public override async Task DeleteAsync(BlobProviderDeleteArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
+ var configuration = args.Configuration.GetAzureConfiguration();
- if (await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName))
+ if (await BlobExistsAsync(configuration, blobName))
{
- return await GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName).DeleteIfExistsAsync();
+ return await GetBlobClient(configuration, blobName).DeleteIfExistsAsync();
}
return false;
@@ -48,19 +49,22 @@ namespace Volo.Abp.BlobStoring.Azure
public override async Task ExistsAsync(BlobProviderExistsArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
- return await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName);
+ var configuration = args.Configuration.GetAzureConfiguration();
+
+ return await BlobExistsAsync(configuration, blobName);
}
public override async Task GetOrNullAsync(BlobProviderGetArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
+ var configuration = args.Configuration.GetAzureConfiguration();
- if (!await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName))
+ if (!await BlobExistsAsync(configuration, blobName))
{
return null;
}
- var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName);
+ var blobClient = GetBlobClient(configuration, blobName);
var download = await blobClient.DownloadAsync();
var memoryStream = new MemoryStream();
await download.Value.Content.CopyToAsync(memoryStream);
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
index a0906ed31f..8c232b7729 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
@@ -8,6 +8,11 @@
set => _containerConfiguration.SetConfiguration(AzureBlobProviderConfigurationNames.ConnectionString, Check.NotNullOrWhiteSpace(value, nameof(value)));
}
+ ///
+ /// This name may only contain lowercase letters, numbers, and hyphens, and must begin with a letter or a number.
+ /// Each hyphen must be preceded and followed by a non-hyphen character.
+ /// The name must also be between 3 and 63 characters long.
+ ///
public string ContainerName
{
get => _containerConfiguration.GetConfiguration(AzureBlobProviderConfigurationNames.ContainerName);
From decdfde0a563437edacc531616f8bc79eac45526 Mon Sep 17 00:00:00 2001
From: maliming <6908465+maliming@users.noreply.github.com>
Date: Wed, 10 Jun 2020 13:08:10 +0800
Subject: [PATCH 8/8] Use ContainerName of the BlobProviderArgs if
ContainerName of the AzureBlobProviderConfiguration is not specified.
---
.../BlobStoring/Azure/AzureBlobProvider.cs | 52 +++++++++++--------
.../Azure/AzureBlobProviderConfiguration.cs | 1 +
2 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
index af5150c0a9..1afc3b6a53 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
@@ -1,7 +1,7 @@
-using System.IO;
+using System;
+using System.IO;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
-using Azure.Storage.Blobs.Specialized;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BlobStoring.Azure
@@ -20,27 +20,26 @@ namespace Volo.Abp.BlobStoring.Azure
var blobName = AzureBlobNameCalculator.Calculate(args);
var configuration = args.Configuration.GetAzureConfiguration();
- if (!args.OverrideExisting && await BlobExistsAsync(configuration, blobName))
+ if (!args.OverrideExisting && await BlobExistsAsync(args, blobName))
{
- throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{configuration.ContainerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
+ throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{GetContainerName(args)}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
}
if (configuration.CreateContainerIfNotExists)
{
- await CreateContainerIfNotExists(configuration);
+ await CreateContainerIfNotExists(args);
}
- await GetBlobClient(configuration, blobName).UploadAsync(args.BlobStream, true);
+ await GetBlobClient(args, blobName).UploadAsync(args.BlobStream, true);
}
public override async Task DeleteAsync(BlobProviderDeleteArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
- var configuration = args.Configuration.GetAzureConfiguration();
- if (await BlobExistsAsync(configuration, blobName))
+ if (await BlobExistsAsync(args, blobName))
{
- return await GetBlobClient(configuration, blobName).DeleteIfExistsAsync();
+ return await GetBlobClient(args, blobName).DeleteIfExistsAsync();
}
return false;
@@ -49,51 +48,58 @@ namespace Volo.Abp.BlobStoring.Azure
public override async Task ExistsAsync(BlobProviderExistsArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
- var configuration = args.Configuration.GetAzureConfiguration();
- return await BlobExistsAsync(configuration, blobName);
+ return await BlobExistsAsync(args, blobName);
}
public override async Task GetOrNullAsync(BlobProviderGetArgs args)
{
var blobName = AzureBlobNameCalculator.Calculate(args);
- var configuration = args.Configuration.GetAzureConfiguration();
- if (!await BlobExistsAsync(configuration, blobName))
+ if (!await BlobExistsAsync(args, blobName))
{
return null;
}
- var blobClient = GetBlobClient(configuration, blobName);
+ var blobClient = GetBlobClient(args, blobName);
var download = await blobClient.DownloadAsync();
var memoryStream = new MemoryStream();
await download.Value.Content.CopyToAsync(memoryStream);
return memoryStream;
}
- protected virtual BlobClient GetBlobClient(AzureBlobProviderConfiguration configuration, string blobName)
+ protected virtual BlobClient GetBlobClient(BlobProviderArgs args, string blobName)
{
- var blobContainerClient = GetBlobContainerClient(configuration);
+ var blobContainerClient = GetBlobContainerClient(args);
return blobContainerClient.GetBlobClient(blobName);
}
- protected virtual BlobContainerClient GetBlobContainerClient(AzureBlobProviderConfiguration configuration)
+ protected virtual BlobContainerClient GetBlobContainerClient(BlobProviderArgs args)
{
+ var configuration = args.Configuration.GetAzureConfiguration();
var blobServiceClient = new BlobServiceClient(configuration.ConnectionString);
- return blobServiceClient.GetBlobContainerClient(configuration.ContainerName);
+ return blobServiceClient.GetBlobContainerClient(GetContainerName(args));
}
- protected virtual async Task CreateContainerIfNotExists(AzureBlobProviderConfiguration configuration)
+ protected virtual async Task CreateContainerIfNotExists(BlobProviderArgs args)
{
- var blobContainerClient = GetBlobContainerClient(configuration);
+ var blobContainerClient = GetBlobContainerClient(args);
await blobContainerClient.CreateIfNotExistsAsync();
}
- private async Task BlobExistsAsync(AzureBlobProviderConfiguration configuration, string blobName)
+ private async Task BlobExistsAsync(BlobProviderArgs args, string blobName)
{
// Make sure Blob Container exists.
- return await ContainerExistsAsync(GetBlobContainerClient(configuration)) &&
- (await GetBlobClient(configuration, blobName).ExistsAsync()).Value;
+ return await ContainerExistsAsync(GetBlobContainerClient(args)) &&
+ (await GetBlobClient(args, blobName).ExistsAsync()).Value;
+ }
+
+ private static string GetContainerName(BlobProviderArgs args)
+ {
+ var configuration = args.Configuration.GetAzureConfiguration();
+ return configuration.ContainerName.IsNullOrWhiteSpace()
+ ? args.ContainerName
+ : configuration.ContainerName;
}
private static async Task ContainerExistsAsync(BlobContainerClient blobContainerClient)
diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
index 8c232b7729..7ab338794b 100644
--- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
+++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs
@@ -12,6 +12,7 @@
/// This name may only contain lowercase letters, numbers, and hyphens, and must begin with a letter or a number.
/// Each hyphen must be preceded and followed by a non-hyphen character.
/// The name must also be between 3 and 63 characters long.
+ /// If this parameter is not specified, the ContainerName of the will be used.
///
public string ContainerName
{