双向同步后端测试完毕
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;
@ -751,69 +751,69 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
try try
{ {
if (fileStream.CanSeek) if (fileStream.CanSeek)
fileStream.Seek(0, SeekOrigin.Begin); fileStream.Seek(0, SeekOrigin.Begin);
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
// 上传文件
var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, fileStream);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
.Build();
var putObjectArgs = new PutObjectArgs()
.WithBucket(minIOConfig.BucketName)
.WithObject(ossRelativePath)
.WithStreamData(fileStream)
.WithObjectSize(fileStream.Length);
await minioClient.PutObjectAsync(putObjectArgs);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var awsConfig = ObjectStoreServiceOptions.AWS;
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{ {
var aliConfig = ObjectStoreServiceOptions.AliyunOSS; RegionEndpoint = RegionEndpoint.GetBySystemName(awsConfig.Region)
//,UseHttp = true,
};
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
var putObjectRequest = new Amazon.S3.Model.PutObjectRequest()
// 上传文件
var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, fileStream);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{ {
var minIOConfig = ObjectStoreServiceOptions.MinIO; BucketName = awsConfig.BucketName,
InputStream = fileStream,
Key = ossRelativePath,
};
await amazonS3Client.PutObjectAsync(putObjectRequest);
var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}") }
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL) else
.Build(); {
throw new BusinessValidationFailedException("未定义的存储介质类型");
var putObjectArgs = new PutObjectArgs() }
.WithBucket(minIOConfig.BucketName)
.WithObject(ossRelativePath)
.WithStreamData(fileStream)
.WithObjectSize(fileStream.Length);
await minioClient.PutObjectAsync(putObjectArgs);
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var awsConfig = ObjectStoreServiceOptions.AWS;
var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);
//提供awsEndPoint域名进行访问配置
var clientConfig = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.GetBySystemName(awsConfig.Region)
//,UseHttp = true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
var putObjectRequest = new Amazon.S3.Model.PutObjectRequest()
{
BucketName = awsConfig.BucketName,
InputStream = fileStream,
Key = ossRelativePath,
};
await amazonS3Client.PutObjectAsync(putObjectRequest);
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -827,7 +827,7 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
if (ObjectStoreServiceOptions.IsOpenStoreSync && uploadInfo != null) if (ObjectStoreServiceOptions.IsOpenStoreSync && uploadInfo != null)
{ {
uploadInfo.FileSize = fileStream.CanSeek ? fileStream.Length : 0; uploadInfo.FileSize = fileStream.CanSeek ? fileStream.Length : 0;
uploadInfo.Path = returnPath; uploadInfo.Path = returnPath;
uploadInfo.FileName = fileRealName; uploadInfo.FileName = fileRealName;
uploadInfo.FileType = Path.GetExtension(returnPath); uploadInfo.FileType = Path.GetExtension(returnPath);
@ -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)
{ {
ObjectStoreUse.AliyunOSS => _ossClient.GetObject(aliConfig.BucketName, objectKey).Content, case ObjectStoreUse.AliyunOSS:
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
{ {
var putRequest = new Amazon.S3.Model.PutObjectRequest // ========= 上传 =========
if (destination == ObjectStoreUse.AWS)
{ {
BucketName = awsConfig.BucketName, var putRequest = new Amazon.S3.Model.PutObjectRequest
Key = objectKey, {
InputStream = sourceStream BucketName = awsConfig.BucketName,
}; Key = objectKey,
InputStream = sourceStream,
Headers = { ContentLength = contentLength }
};
await amazonS3Client.PutObjectAsync(putRequest, ct); await amazonS3Client.PutObjectAsync(putRequest, ct);
}
else if (destination == ObjectStoreUse.AliyunOSS)
{
_ossClient.PutObject(
aliConfig.BucketName,
objectKey,
sourceStream);
}
else
{
throw new BusinessValidationFailedException("未定义的同步类型");
}
} }
else if (source == ObjectStoreUse.AWS) catch (Exception ex)
{ {
_ossClient.PutObject(aliConfig.BucketName, objectKey, sourceStream); Log.Error($"同步错误:{ex.Message}");
} }
else finally
{ {
throw new BusinessValidationFailedException("未定义的同步类型"); // ⭐⭐⭐ 真正释放 HTTP 连接
owner?.Dispose();
} }
await sourceStream.DisposeAsync(); // 释放流
} }
} }

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);
} }