双向同步后端测试完毕
continuous-integration/drone/push Build is passing Details

Test_IRC_Net8
hang 2026-03-18 13:43:02 +08:00
parent 89fb8eac00
commit c833c88fe3
3 changed files with 127 additions and 82 deletions

View File

@ -32,7 +32,7 @@
"ApiDeployRegion": "CN", "ApiDeployRegion": "CN",
"SyncConfigList": [ "SyncConfigList": [
{ {
"Domain": "ir.test.extimaging.com", "Domain": "irc.test.extimaging.com",
"Primary": "AliyunOSS", "Primary": "AliyunOSS",
"Target": "AWS", "Target": "AWS",
"UploadRegion": "CN", "UploadRegion": "CN",

View File

@ -7,6 +7,7 @@ using Amazon.S3;
using Amazon.S3.Model; using Amazon.S3.Model;
using Amazon.SecurityToken; using Amazon.SecurityToken;
using Amazon.SecurityToken.Model; using Amazon.SecurityToken.Model;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
@ -18,7 +19,6 @@ using Minio;
using Minio.DataModel; using Minio.DataModel;
using Minio.DataModel.Args; using Minio.DataModel.Args;
using Minio.Exceptions; using Minio.Exceptions;
using Org.BouncyCastle.Tls;
using Serilog.Parsing; using Serilog.Parsing;
using SkiaSharp; using SkiaSharp;
using System.IO; using System.IO;
@ -1922,11 +1922,11 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
objectStoreDTO.AliyunOSS = tempToken; objectStoreDTO.AliyunOSS = tempToken;
} }
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{ {
objectStoreDTO.MinIO = ObjectStoreServiceOptions.MinIO; objectStoreDTO.MinIO = ObjectStoreServiceOptions.MinIO;
} }
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS" || isGetAllTempToken == true) if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS" || isGetAllTempToken == true)
{ {
var awsOptions = ObjectStoreServiceOptions.AWS; var awsOptions = ObjectStoreServiceOptions.AWS;
@ -1982,7 +1982,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;
@ -2001,36 +2001,81 @@ 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(); // 释放流 catch (Exception ex)
{
Log.Error($"同步错误:{ex.Message}");
}
finally
{
// ⭐⭐⭐ 真正释放 HTTP 连接
owner?.Dispose();
}
} }
} }

View File

@ -117,7 +117,7 @@ namespace IRaCIS.Core.Application.Service
//await WeComNotifier.SendErrorAsync(webhook, "http://irc.test.extimaging.com/login", new Exception("测试异常"), new[] { "ZhouHang" }); //await WeComNotifier.SendErrorAsync(webhook, "http://irc.test.extimaging.com/login", new Exception("测试异常"), new[] { "ZhouHang" });
//throw new Exception("手动测试异常抛出"); //throw new Exception("手动测试异常抛出");
return ResponseOutput.Ok(modelVerify); return ResponseOutput.Ok(_userInfo.Domain);
} }