diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index b507b0813..baa34b64f 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -379,7 +379,8 @@ namespace IRaCIS.Api.Controllers SecretAccessKey = credentials.SecretAccessKey, SessionToken= credentials.SessionToken, Expiration=credentials.Expiration, - + Region=awsOptions.Region, + BucketName = awsOptions.BucketName, EndPoint = awsOptions.EndPoint, ViewEndpoint = awsOptions.ViewEndpoint, @@ -421,7 +422,7 @@ namespace IRaCIS.Api.Controllers SecretAccessKey = credentials.SecretAccessKey, SessionToken = credentials.SessionToken, Expiration = credentials.Expiration, - + Region = awsOptions.Region, BucketName = awsOptions.BucketName, EndPoint = awsOptions.EndPoint, ViewEndpoint = awsOptions.ViewEndpoint, diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 3138ca442..078086d1d 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -37,6 +37,7 @@ "ViewEndpoint": "https://hir-oss.test.extimaging.com/irc-test" }, "AWS": { + "Region": "us-east-1", "EndPoint": "s3.us-east-1.amazonaws.com", "UseSSL": true, "RoleArn": "arn:aws:iam::471112624751:role/sts_s3_upload", diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index 2c28d3be2..061150189 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -20,9 +20,15 @@ using System.Reactive.Linq; using IRaCIS.Core.Domain.Share; using static MassTransit.ValidationResultExtensions; using IRaCIS.Core.Infrastructure.NewtonsoftJson; +using Amazon.Runtime; +using Amazon.S3; +using Amazon.S3.Model; +using MassTransit.Caching.Internals; namespace IRaCIS.Core.Application.Helper { + #region 绑定和返回模型 + [LowerCamelCaseJson] public class MinIOOptions : AWSOptions { @@ -30,7 +36,7 @@ namespace IRaCIS.Core.Application.Helper } - + public class AWSOptions { public string EndPoint { get; set; } @@ -41,6 +47,7 @@ namespace IRaCIS.Core.Application.Helper public string BucketName { get; set; } public string ViewEndpoint { get; set; } public int DurationSeconds { get; set; } + public string Region { get; set; } } public class AliyunOSSOptions @@ -118,6 +125,7 @@ namespace IRaCIS.Core.Application.Helper [LowerCamelCaseJson] public class AWSTempToken { + public string Region { get; set; } public string SessionToken { get; set; } public string EndPoint { get; set; } public string AccessKeyId { get; set; } @@ -134,6 +142,10 @@ namespace IRaCIS.Core.Application.Helper AWS = 2, } + #endregion + + // aws 参考链接 https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/S3/S3_Basics + public interface IOSSService { public Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true); @@ -170,8 +182,6 @@ namespace IRaCIS.Core.Application.Helper public async Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true) { var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}"; - //var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}"; - //var ossRelativePath = oosFolderPath + "/" + fileRealName; try { @@ -215,20 +225,27 @@ namespace IRaCIS.Core.Application.Helper } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { - var minIOConfig = ObjectStoreServiceOptions.AWS; + var awsConfig = ObjectStoreServiceOptions.AWS; + // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 + var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}") - .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) - .Build(); + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + ServiceURL = awsConfig.EndPoint + }; - var putObjectArgs = new PutObjectArgs() - .WithBucket(minIOConfig.BucketName) - .WithObject(ossRelativePath) - .WithStreamData(memoryStream) - .WithObjectSize(memoryStream.Length); + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); - await minioClient.PutObjectAsync(putObjectArgs); + var putObjectRequest = new Amazon.S3.Model.PutObjectRequest() + { + BucketName = awsConfig.BucketName, + InputStream = memoryStream, + Key = ossRelativePath, + }; + + await amazonS3Client.PutObjectAsync(putObjectRequest); } else { @@ -256,6 +273,7 @@ namespace IRaCIS.Core.Application.Helper /// /// /// + /// /// /// public async Task UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true) @@ -265,9 +283,6 @@ namespace IRaCIS.Core.Application.Helper var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}"; - //var ossRelativePath = oosFolderPath + "/" + localFileName; - - if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; @@ -296,19 +311,28 @@ namespace IRaCIS.Core.Application.Helper } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { - var minIOConfig = ObjectStoreServiceOptions.AWS; + var awsConfig = ObjectStoreServiceOptions.AWS; + // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 + var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}") - .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) - .Build(); + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + ServiceURL = awsConfig.EndPoint + }; - var putObjectArgs = new PutObjectArgs() - .WithBucket(minIOConfig.BucketName) - .WithObject(ossRelativePath) - .WithFileName(localFilePath); + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); + + var putObjectRequest = new Amazon.S3.Model.PutObjectRequest() + { + BucketName = awsConfig.BucketName, + FilePath = localFilePath, + Key = ossRelativePath, + }; + + await amazonS3Client.PutObjectAsync(putObjectRequest); - await minioClient.PutObjectAsync(putObjectArgs); } else { @@ -321,7 +345,7 @@ namespace IRaCIS.Core.Application.Helper public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath) { - + ossRelativePath = ossRelativePath.TrimStart('/'); try { @@ -362,18 +386,29 @@ namespace IRaCIS.Core.Application.Helper } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { - var minIOConfig = ObjectStoreServiceOptions.AWS; + var awsConfig = ObjectStoreServiceOptions.AWS; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}") - .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) - .Build(); + // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 + var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); + + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + ServiceURL = awsConfig.EndPoint + }; + + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); + + var getObjectArgs = new Amazon.S3.Model.GetObjectRequest() + { + BucketName = awsConfig.BucketName, + Key = ossRelativePath, + }; + + + await (await amazonS3Client.GetObjectAsync(getObjectArgs)).WriteResponseStreamToFileAsync(localFilePath, true, CancellationToken.None); - var getObjectArgs = new GetObjectArgs() - .WithBucket(minIOConfig.BucketName) - .WithObject(ossRelativePath) - .WithFile(localFilePath); - await minioClient.GetObjectAsync(getObjectArgs); } else { @@ -497,7 +532,7 @@ namespace IRaCIS.Core.Application.Helper do { // 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker - objectListing = _ossClient.ListObjects(new ListObjectsRequest(aliConfig.BucketName) + objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName) { Prefix = prefix, MaxKeys = 1000, @@ -509,7 +544,7 @@ namespace IRaCIS.Core.Application.Helper // 删除获取到的文件 if (keys.Count > 0) { - _ossClient.DeleteObjects(new DeleteObjectsRequest(aliConfig.BucketName, keys, false)); + _ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(aliConfig.BucketName, keys, false)); } // 设置 NextMarker 以获取下一页的数据 @@ -538,7 +573,15 @@ namespace IRaCIS.Core.Application.Helper - var objects = minioClient.ListObjectsAsync(listArgs).ToListObservable().Select(t => t.Key).ToList(); + // 创建一个空列表用于存储对象键 + var objects = new List(); + + // 使用 await foreach 来异步迭代对象列表 + await foreach (var item in minioClient.ListObjectsEnumAsync(listArgs)) + { + objects.Add(item.Key); + } + if (objects.Count > 0) { @@ -555,7 +598,53 @@ namespace IRaCIS.Core.Application.Helper } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { - throw new BusinessValidationFailedException("未定义的存储介质类型"); + + var awsConfig = ObjectStoreServiceOptions.AWS; + + + // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 + var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); + + //提供awsEndPoint(域名)进行访问配置 + var clientConfig = new AmazonS3Config + { + ServiceURL = awsConfig.EndPoint + }; + + var amazonS3Client = new AmazonS3Client(credentials, clientConfig); + + // 列出指定前缀下的所有对象 + var listObjectsRequest = new ListObjectsV2Request + { + BucketName = awsConfig.BucketName, + Prefix = prefix + }; + + var listObjectsResponse = await amazonS3Client.ListObjectsV2Async(listObjectsRequest); + + if (listObjectsResponse.S3Objects.Count > 0) + { + // 准备删除请求 + var deleteObjectsRequest = new Amazon.S3.Model.DeleteObjectsRequest + { + BucketName = awsConfig.BucketName, + Objects = new List() + }; + + foreach (var s3Object in listObjectsResponse.S3Objects) + { + deleteObjectsRequest.Objects.Add(new KeyVersion + { + Key = s3Object.Key + }); + } + + // 批量删除对象 + var deleteObjectsResponse = await amazonS3Client.DeleteObjectsAsync(deleteObjectsRequest); + } + + + } else { diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index daa98ea98..c1eb5c0a7 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -59,6 +59,7 @@ +