Compatible with multi-tenancy.

pull/4200/head
maliming 5 years ago
parent 3acc5c8c85
commit 057c4c1a25

@ -12,11 +12,11 @@ namespace Volo.Abp.BlobStoring.Azure
public static BlobContainerConfiguration UseAzure(
this BlobContainerConfiguration containerConfiguration,
Action<AzureBlobProviderConfiguration> fileSystemConfigureAction)
Action<AzureBlobProviderConfiguration> azureConfigureAction)
{
containerConfiguration.ProviderType = typeof(AzureBlobProvider);
fileSystemConfigureAction(new AzureBlobProviderConfiguration(containerConfiguration));
azureConfigureAction(new AzureBlobProviderConfiguration(containerConfiguration));
return containerConfiguration;
}

@ -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<bool> 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<bool> 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<Stream> 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<bool> BlobExistsAsync(BlobClient blobClient)
private static async Task<bool> BlobExistsAsync(BlobBaseClient blobClient)
{
return (await blobClient.ExistsAsync()).Value;
}

@ -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}";
}
}
}

@ -0,0 +1,7 @@
namespace Volo.Abp.BlobStoring.Azure
{
public interface IAzureBlobNameCalculator
{
string Calculate(BlobProviderArgs args);
}
}

@ -2,6 +2,14 @@
namespace Volo.Abp.BlobStoring.Azure
{
public class AbpBlobStoringAzureTestCommonBase : AbpIntegratedTest<AbpBlobStoringAzureTestCommonModule>
{
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
options.UseAutofac();
}
}
public class AbpBlobStoringAzureTestBase : AbpIntegratedTest<AbpBlobStoringAzureTestModule>
{
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)

@ -6,10 +6,22 @@ using Volo.Abp.Modularity;
namespace Volo.Abp.BlobStoring.Azure
{
/// <summary>
/// This module will not try to connect to azure.
/// </summary>
[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<IConfiguration>();
var blobServiceClient = new BlobServiceClient(_connectionString);
blobServiceClient.DeleteBlobContainer(_randomContainerName);
}
}
}

@ -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<IAzureBlobNameCalculator>();
_currentTenant = GetRequiredService<ICurrentTenant>();
}
[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
);
}
}
}
Loading…
Cancel
Save