增加同步配置
continuous-integration/drone/push Build is running
Details
continuous-integration/drone/push Build is running
Details
parent
ad5c36930e
commit
592de4deb4
|
|
@ -194,7 +194,7 @@ public interface IOSSService
|
||||||
|
|
||||||
List<string> GetRootFolderNames();
|
List<string> GetRootFolderNames();
|
||||||
|
|
||||||
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null);
|
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null, string? objectUse = null);
|
||||||
|
|
||||||
public Task MoveObject(string sourcePath, string destPath, bool overwrite = true);
|
public Task MoveObject(string sourcePath, string destPath, bool overwrite = true);
|
||||||
|
|
||||||
|
|
@ -1856,23 +1856,39 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null)
|
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null, string? objectUse = null)
|
||||||
|
{
|
||||||
|
string objectStoreUse = string.Empty;
|
||||||
|
//使用指定配置
|
||||||
|
if (objectUse != null)
|
||||||
|
{
|
||||||
|
objectStoreUse = objectUse?.Trim() ?? string.Empty;
|
||||||
|
}
|
||||||
|
//根据域名动态判断
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//如果传递了域名,并且打开了存储同步,根据域名使用的具体存储覆盖之前的配置,否则就用固定的配置
|
//如果传递了域名,并且打开了存储同步,根据域名使用的具体存储覆盖之前的配置,否则就用固定的配置
|
||||||
if (ObjectStoreServiceOptions.IsOpenStoreSync && domain.IsNotNullOrEmpty())
|
if (ObjectStoreServiceOptions.IsOpenStoreSync && domain.IsNotNullOrEmpty() && ObjectStoreServiceOptions.SyncConfigList.Any(t => t.Domain == domain))
|
||||||
{
|
{
|
||||||
var userDomain = domain?.Trim();
|
|
||||||
|
|
||||||
var find = ObjectStoreServiceOptions.SyncConfigList.FirstOrDefault(t => t.Domain == userDomain);
|
var find = ObjectStoreServiceOptions.SyncConfigList.FirstOrDefault(t => t.Domain == domain);
|
||||||
if (find != null)
|
if (find != null)
|
||||||
{
|
{
|
||||||
ObjectStoreServiceOptions.ObjectStoreUse = find.Primary;
|
objectStoreUse = find.Primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//兜底,如果是本地测试环境,那就使用部署默认配置
|
||||||
|
objectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectStoreDTO = new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, IsOpenStoreSync = ObjectStoreServiceOptions.IsOpenStoreSync, SyncConfigList = ObjectStoreServiceOptions.SyncConfigList };
|
|
||||||
|
|
||||||
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS" || isGetAllTempToken == true)
|
var objectStoreDTO = new ObjectStoreDTO() { ObjectStoreUse = objectStoreUse, IsOpenStoreSync = ObjectStoreServiceOptions.IsOpenStoreSync, SyncConfigList = ObjectStoreServiceOptions.SyncConfigList };
|
||||||
|
|
||||||
|
if (objectStoreUse == "AliyunOSS" || isGetAllTempToken == true)
|
||||||
{
|
{
|
||||||
var ossOptions = ObjectStoreServiceOptions.AliyunOSS;
|
var ossOptions = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
||||||
|
|
@ -1920,11 +1936,11 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||||
objectStoreDTO.AliyunOSS = tempToken;
|
objectStoreDTO.AliyunOSS = tempToken;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
if (objectStoreUse == "MinIO")
|
||||||
{
|
{
|
||||||
objectStoreDTO.MinIO = ObjectStoreServiceOptions.MinIO;
|
objectStoreDTO.MinIO = ObjectStoreServiceOptions.MinIO;
|
||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS" || isGetAllTempToken == true)
|
if (objectStoreUse == "AWS" || isGetAllTempToken == true)
|
||||||
{
|
{
|
||||||
var awsOptions = ObjectStoreServiceOptions.AWS;
|
var awsOptions = ObjectStoreServiceOptions.AWS;
|
||||||
|
|
||||||
|
|
@ -1969,7 +1985,8 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||||
|
|
||||||
objectStoreDTO.AWS = tempToken;
|
objectStoreDTO.AWS = tempToken;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (objectStoreUse.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||||
}
|
}
|
||||||
|
|
@ -1980,7 +1997,7 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||||
|
|
||||||
public async Task SyncFileAsync(string objectKey, ObjectStoreUse source, ObjectStoreUse destination, CancellationToken ct = default)
|
public async Task SyncFileAsync(string objectKey, ObjectStoreUse source, ObjectStoreUse destination, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
GetObjectStoreTempToken(isGetAllTempToken: true);
|
var tempConfig = GetObjectStoreTempToken(isGetAllTempToken: true);
|
||||||
|
|
||||||
|
|
||||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||||
|
|
@ -1999,36 +2016,76 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||||
|
|
||||||
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||||
|
|
||||||
|
// ⭐ 关键变量
|
||||||
|
IDisposable? owner = null;
|
||||||
|
Stream sourceStream;
|
||||||
|
long contentLength;
|
||||||
|
|
||||||
// 根据源选择流式下载
|
// ========= 获取流 + 长度 =========
|
||||||
Stream sourceStream = source switch
|
switch (source)
|
||||||
|
{
|
||||||
|
case ObjectStoreUse.AliyunOSS:
|
||||||
{
|
{
|
||||||
ObjectStoreUse.AliyunOSS => _ossClient.GetObject(aliConfig.BucketName, objectKey).Content,
|
|
||||||
ObjectStoreUse.AWS => (await amazonS3Client.GetObjectAsync(awsConfig.BucketName, objectKey, ct)).ResponseStream,
|
|
||||||
_ => throw new BusinessValidationFailedException("未定义的同步类型")
|
|
||||||
};
|
|
||||||
|
|
||||||
if (source == ObjectStoreUse.AliyunOSS)
|
var obj = _ossClient.GetObject(
|
||||||
|
aliConfig.BucketName,
|
||||||
|
objectKey);
|
||||||
|
|
||||||
|
owner = obj;
|
||||||
|
sourceStream = obj.Content;
|
||||||
|
contentLength = obj.ContentLength;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ObjectStoreUse.AWS:
|
||||||
|
{
|
||||||
|
var response = await amazonS3Client.GetObjectAsync(
|
||||||
|
awsConfig.BucketName,
|
||||||
|
objectKey,
|
||||||
|
ct);
|
||||||
|
|
||||||
|
owner = response;
|
||||||
|
sourceStream = response.ResponseStream;
|
||||||
|
contentLength = response.Headers.ContentLength;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new BusinessValidationFailedException("未定义的同步类型");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// ========= 上传 =========
|
||||||
|
if (destination == ObjectStoreUse.AWS)
|
||||||
{
|
{
|
||||||
var putRequest = new Amazon.S3.Model.PutObjectRequest
|
var putRequest = new Amazon.S3.Model.PutObjectRequest
|
||||||
{
|
{
|
||||||
BucketName = awsConfig.BucketName,
|
BucketName = awsConfig.BucketName,
|
||||||
Key = objectKey,
|
Key = objectKey,
|
||||||
InputStream = sourceStream
|
InputStream = sourceStream,
|
||||||
|
Headers = { ContentLength = contentLength }
|
||||||
};
|
};
|
||||||
|
|
||||||
await amazonS3Client.PutObjectAsync(putRequest, ct);
|
await amazonS3Client.PutObjectAsync(putRequest, ct);
|
||||||
}
|
}
|
||||||
else if (source == ObjectStoreUse.AWS)
|
else if (destination == ObjectStoreUse.AliyunOSS)
|
||||||
{
|
{
|
||||||
_ossClient.PutObject(aliConfig.BucketName, objectKey, sourceStream);
|
_ossClient.PutObject(
|
||||||
|
aliConfig.BucketName,
|
||||||
|
objectKey,
|
||||||
|
sourceStream);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new BusinessValidationFailedException("未定义的同步类型");
|
throw new BusinessValidationFailedException("未定义的同步类型");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
await sourceStream.DisposeAsync(); // 释放流
|
finally
|
||||||
|
{
|
||||||
|
// ⭐⭐⭐ 真正释放 HTTP 连接
|
||||||
|
owner?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
using AutoMapper;
|
||||||
|
using IRaCIS.Core.Domain.Models;
|
||||||
|
using IRaCIS.Core.SCP.Service;
|
||||||
|
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.Service
|
||||||
|
{
|
||||||
|
public class CommonConfig : Profile
|
||||||
|
{
|
||||||
|
public CommonConfig()
|
||||||
|
{
|
||||||
|
CreateMap<FileUploadRecordAddOrEdit, FileUploadRecord>().ReverseMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -50,6 +50,27 @@
|
||||||
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
||||||
"bucketName": "hir-test",
|
"bucketName": "hir-test",
|
||||||
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
|
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
|
||||||
|
},
|
||||||
|
// AWS S3 对象存储服务的配置
|
||||||
|
"AWS": {
|
||||||
|
// AWS S3 的Region
|
||||||
|
"Region": "us-east-1",
|
||||||
|
// AWS S3 的内部访问端点
|
||||||
|
"EndPoint": "s3.us-east-1.amazonaws.com",
|
||||||
|
// 是否使用 SSL
|
||||||
|
"UseSSL": true,
|
||||||
|
// AWS S3 的角色 ARN
|
||||||
|
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
|
||||||
|
// AWS S3 的访问密钥 ID
|
||||||
|
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
|
||||||
|
// AWS S3 的访问密钥 Secret
|
||||||
|
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
|
||||||
|
// AWS S3 的Bucket名称
|
||||||
|
"BucketName": "ei-med-s3-lili-uat-store",
|
||||||
|
// AWS S3 的访问端点
|
||||||
|
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
||||||
|
// AWS S3 的持续数秒
|
||||||
|
"DurationSeconds": 7200
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue