Browse Source

Make region optional for some S3 compatible APIs

pull/22962/head
enisn 1 year ago
parent
commit
4f2a141046
No known key found for this signature in database GPG Key ID: A052619F04155D1C
  1. 6
      framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProviderConfiguration.cs
  2. 15
      framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/DefaultAmazonS3ClientFactory.cs
  3. 38
      framework/test/Volo.Abp.BlobStoring.Aws.Tests/Volo/Abp/BlobStoring/Aws/AbpBlobStoringAwsTestModule.cs
  4. 23
      framework/test/Volo.Abp.BlobStoring.Aws.Tests/Volo/Abp/BlobStoring/Aws/DefaultAmazonS3ClientFactory_Tests.cs

6
framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProviderConfiguration.cs

@ -57,9 +57,9 @@ public class AwsBlobProviderConfiguration
set => _containerConfiguration.SetConfiguration(AwsBlobProviderConfigurationNames.Policy, value);
}
public string Region {
get => _containerConfiguration.GetConfiguration<string>(AwsBlobProviderConfigurationNames.Region);
set => _containerConfiguration.SetConfiguration(AwsBlobProviderConfigurationNames.Region, Check.NotNull(value, nameof(value)));
public string? Region {
get => _containerConfiguration.GetConfigurationOrDefault<string>(AwsBlobProviderConfigurationNames.Region);
set => _containerConfiguration.SetConfiguration(AwsBlobProviderConfigurationNames.Region, value);
}
/// <summary>

15
framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/DefaultAmazonS3ClientFactory.cs

@ -30,7 +30,9 @@ public class DefaultAmazonS3ClientFactory : IAmazonS3ClientFactory, ITransientDe
public virtual async Task<AmazonS3Client> GetAmazonS3Client(
AwsBlobProviderConfiguration configuration)
{
var region = RegionEndpoint.GetBySystemName(configuration.Region);
var region = !configuration.Region.IsNullOrWhiteSpace()
? RegionEndpoint.GetBySystemName(configuration.Region)
: null;
var clientConfig = CreateS3ClientConfig(configuration, region);
if (configuration.UseCredentials)
@ -58,12 +60,15 @@ public class DefaultAmazonS3ClientFactory : IAmazonS3ClientFactory, ITransientDe
return new AmazonS3Client(configuration.AccessKeyId, configuration.SecretAccessKey, clientConfig);
}
protected virtual AmazonS3Config CreateS3ClientConfig(AwsBlobProviderConfiguration configuration, RegionEndpoint region)
protected virtual AmazonS3Config CreateS3ClientConfig(AwsBlobProviderConfiguration configuration, RegionEndpoint? region)
{
var clientConfig = new AmazonS3Config
var clientConfig = new AmazonS3Config();
// Set region only if it's provided (for AWS S3)
if (region != null)
{
RegionEndpoint = region
};
clientConfig.RegionEndpoint = region;
}
if (!configuration.ServiceURL.IsNullOrWhiteSpace())
{

38
framework/test/Volo.Abp.BlobStoring.Aws.Tests/Volo/Abp/BlobStoring/Aws/AbpBlobStoringAwsTestModule.cs

@ -69,23 +69,39 @@ public class AbpBlobStoringAwsTestModule : AbpModule
private async Task DeleteBucketAsync(ApplicationShutdownContext context)
{
var amazonS3Client = await context.ServiceProvider.GetRequiredService<IAmazonS3ClientFactory>()
.GetAmazonS3Client(_configuration);
// Skip bucket deletion if configuration is not properly set (e.g., in unit tests)
if (_configuration == null ||
string.IsNullOrWhiteSpace(_configuration.AccessKeyId) ||
string.IsNullOrWhiteSpace(_configuration.SecretAccessKey) ||
(string.IsNullOrWhiteSpace(_configuration.Region) && string.IsNullOrWhiteSpace(_configuration.ServiceURL)))
{
return;
}
if (await AmazonS3Util.DoesS3BucketExistV2Async(amazonS3Client, _randomContainerName))
try
{
var blobs = await amazonS3Client.ListObjectsAsync(_randomContainerName);
var amazonS3Client = await context.ServiceProvider.GetRequiredService<IAmazonS3ClientFactory>()
.GetAmazonS3Client(_configuration);
if (blobs.S3Objects.Any())
if (await AmazonS3Util.DoesS3BucketExistV2Async(amazonS3Client, _randomContainerName))
{
await amazonS3Client.DeleteObjectsAsync(new DeleteObjectsRequest
var blobs = await amazonS3Client.ListObjectsAsync(_randomContainerName);
if (blobs.S3Objects.Any())
{
BucketName = _randomContainerName,
Objects = blobs.S3Objects.Select(o => new KeyVersion { Key = o.Key }).ToList()
});
}
await amazonS3Client.DeleteObjectsAsync(new DeleteObjectsRequest
{
BucketName = _randomContainerName,
Objects = blobs.S3Objects.Select(o => new KeyVersion { Key = o.Key }).ToList()
});
}
await amazonS3Client.DeleteBucketAsync(_randomContainerName);
await amazonS3Client.DeleteBucketAsync(_randomContainerName);
}
}
catch
{
// Ignore errors during test cleanup
}
}
}

23
framework/test/Volo.Abp.BlobStoring.Aws.Tests/Volo/Abp/BlobStoring/Aws/DefaultAmazonS3ClientFactory_Tests.cs

@ -61,4 +61,27 @@ public class DefaultAmazonS3ClientFactory_Tests : AbpBlobStoringAwsTestBase
s3Client.Config.ServiceURL.ShouldBeNull(); // Should use default AWS S3 service
((AmazonS3Config)s3Client.Config).ForcePathStyle.ShouldBeFalse(); // Should be false for AWS S3
}
[Fact]
public async Task Should_Create_S3Client_Without_Region_For_S3Compatible_Services()
{
// Arrange
var containerConfiguration = new BlobContainerConfiguration();
var awsConfiguration = new AwsBlobProviderConfiguration(containerConfiguration)
{
AccessKeyId = "test-access-key",
SecretAccessKey = "test-secret-key",
ServiceURL = "https://minio.example.com:9000"
// Region not set - should work for S3-compatible services
};
// Act
using var s3Client = await _amazonS3ClientFactory.GetAmazonS3Client(awsConfiguration);
// Assert
s3Client.ShouldNotBeNull();
s3Client.Config.ServiceURL.ShouldBe("https://minio.example.com:9000/"); // AWS SDK automatically appends trailing slash
((AmazonS3Config)s3Client.Config).ForcePathStyle.ShouldBeTrue(); // Should be enabled for S3-compatible services
}
}
Loading…
Cancel
Save