Files
caliverse_server/ServerCore/S3/S3ConnectorBase.cs
2025-11-28 16:54:56 +09:00

395 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
using System.Net;
using Amazon.DynamoDBv2.Model;
using Amazon.DynamoDBv2;
using Amazon.S3;
using Amazon.Internal;
using Amazon;
using Amazon.S3.Model;
using Amazon.Runtime.Internal;
namespace ServerCore;
// HANDOVER: AWS S3 SDK Wrapper 클래스 이다.
// S3 저장소에 관리할 Bucket 정보를 관리해 준다.
public abstract class S3ConnectorBase
{
private AmazonS3Client? m_s3_client;
private string m_access_key = string.Empty;
private string m_secret_key = string.Empty;
private string m_region = string.Empty;
public bool createS3Client(string accessKey, string secretKey, string region)
{
try
{
m_access_key = accessKey;
m_secret_key = secretKey;
m_region = region;
var regionEndpoint = RegionEndpoint.GetBySystemName(region);
// 여기서 실제로 연결 시도는 하지 않는다 !!!, 단순 초기화
m_s3_client = new AmazonS3Client(accessKey, secretKey, regionEndpoint);
}
catch (Exception e)
{
Log.getLogger().error($"Exception !!!, Failed to perform in createS3Client() : accessKey:{accessKey}, secretKey:{secretKey}, region:{region}, exception:{e}");
return false;
}
return true;
}
public async Task<(bool, List<S3Bucket>)> getBuckets()
{
var buckets = new List<S3Bucket>();
try
{
NullReferenceCheckHelper.throwIfNull(m_s3_client, () => $"m_s3_client is null !!!");
var response = await m_s3_client.ListBucketsAsync();
if (response.HttpStatusCode != HttpStatusCode.OK)
{
Log.getLogger().fatal($"Failed to ListBucketsAsync() !!! : HttpStatusCode:{response.HttpStatusCode}");
return (false, buckets);
}
return (true, response.Buckets);
}
catch (Exception e)
{
Log.getLogger().fatal($"Exception !!!, Failed to perfrom in getBuckets() !!! : exception:{e}");
}
return (false, buckets);
}
public async Task<bool> createBucket(PutBucketRequest request)
{
try
{
NullReferenceCheckHelper.throwIfNull(m_s3_client, () => $"m_s3_client is null !!!");
var response = await m_s3_client.PutBucketAsync(request);
if (response.HttpStatusCode != HttpStatusCode.OK)
{
Log.getLogger().fatal($"Failed to PutBucketAsync() !!! : HttpStatusCode:{response.HttpStatusCode}");
return false;
}
}
catch (Exception e)
{
Log.getLogger().fatal($"Exception !!!, Failed to perfrom in createBucket() !!! : exception:{e}");
return false;
}
return true;
}
public async Task<bool> uploadFile(PutObjectRequest request)
{
try
{
NullReferenceCheckHelper.throwIfNull(m_s3_client, () => $"m_s3_client is null !!!");
var response = await m_s3_client.PutObjectAsync(request);
if (response.HttpStatusCode != HttpStatusCode.OK)
{
Log.getLogger().fatal($"Failed to PutObjectAsync() !!! : HttpStatusCode:{response.HttpStatusCode}");
return false;
}
}
catch (Exception e)
{
Log.getLogger().fatal($"Exception !!!, Failed to perform in uploadFile() : exception:{e}");
return false;
}
return true;
}
public async Task<bool> deleteFile(DeleteObjectRequest request)
{
try
{
NullReferenceCheckHelper.throwIfNull(m_s3_client, () => $"m_s3_client is null !!!");
var response = await m_s3_client.DeleteObjectAsync(request);
if (response.HttpStatusCode != HttpStatusCode.NoContent)
{
Log.getLogger().fatal($"Failed to DeleteObjectAsync() !!!, in deleteFile() : HttpStatusCode:{response.HttpStatusCode}");
return false;
}
}
catch (Exception e)
{
Log.getLogger().fatal($"Exception !!!, Failed to perform in deleteFile() : exception:{e}");
return false;
}
return true;
}
public async Task<bool> deleteFolderFile(ListObjectsV2Request request)
{
try
{
ListObjectsV2Response response;
do
{
NullReferenceCheckHelper.throwIfNull(m_s3_client, () => $"m_s3_client is null !!!");
response = await m_s3_client.ListObjectsV2Async(request);
if (response.HttpStatusCode != HttpStatusCode.OK)
{
Log.getLogger().fatal($"Failed to ListObjectsV2Async() !!!, in deleteFolderFile() : HttpStatusCode:{response.HttpStatusCode}");
return false;
}
if (response.S3Objects.Count == 0)
{
return true;
}
var delete_request = new DeleteObjectsRequest
{
BucketName = request.BucketName,
};
foreach (var s3_object in response.S3Objects)
{
delete_request.AddKey(s3_object.Key);
}
var delete_response = await m_s3_client.DeleteObjectsAsync(delete_request);
if (response.HttpStatusCode != HttpStatusCode.OK)
{
Log.getLogger().fatal($"Failed to DeleteObjectsAsync() !!!, in deleteFolderFile() : HttpStatusCode:{response.HttpStatusCode}");
return false;
}
request.ContinuationToken = response.NextContinuationToken;
}
while (response.IsTruncated);
}
catch (Exception e)
{
Log.getLogger().fatal($"Exception !!!, Failed to perform in deleteFolderFile() : exception:{e}");
return false;
}
return true;
}
public async Task<(bool, Stream?)> getFileStream(GetObjectRequest request)
{
try
{
NullReferenceCheckHelper.throwIfNull(m_s3_client, () => $"m_s3_client is null !!!");
var response = await m_s3_client.GetObjectAsync(request);
if (response.HttpStatusCode != HttpStatusCode.OK)
{
Log.getLogger().fatal($"Failed to GetObjectAsync() !!! : HttpStatusCode:{response.HttpStatusCode}");
return (false, null);
}
return (true, response.ResponseStream);
}
catch (Exception e)
{
Log.getLogger().fatal($"Exception !!!, Failed to perform in getFileStream() : exception:{e}");
}
return (false, null);
}
private async Task<(bool, string)> generatePreSignedUrl(GetPreSignedUrlRequest request)
{
try
{
NullReferenceCheckHelper.throwIfNull(m_s3_client, () => $"m_s3_client is null !!!");
var presigned_url = await m_s3_client.GetPreSignedURLAsync(request);
return (true, presigned_url);
}
catch (Exception e)
{
Log.getLogger().fatal($"Exception !!!, Failed to perform in generatePresignedUrl() : exception:{e}");
}
return (false, string.Empty);
}
public async Task<bool> createBucketIfNotExist(string bucketName)
{
if (false == await isExistBucket(bucketName))
{
var request = new PutBucketRequest
{
BucketName = bucketName,
UseClientRegion = true,
};
if (false == await createBucket(request))
{
var err_msg = $"Failed to createBucket() !!! : bucketName:{bucketName}";
Log.getLogger().error(err_msg);
return false;
}
}
return true;
}
public async Task<bool> isExistBucket(string bucketName)
{
(var is_success, var buckets) = await getBuckets();
if (false == is_success)
{
return false;
}
foreach (var bucket in buckets)
{
if (bucket.BucketName == bucketName) return true;
}
return false;
}
public async Task<bool> tryUploadFile(string bucketName, string s3Key, string data)
{
var err_msg = string.Empty;
using (var memory_stream = data.toStream())
{
var request = new PutObjectRequest
{
BucketName = bucketName,
Key = s3Key,
InputStream = memory_stream,
};
if (false == await uploadFile(request))
{
err_msg = $"Failed to uploadFile() !!!, in tryUploadFile() : bucketName:{bucketName}, s3Key:{s3Key}";
Log.getLogger().error(err_msg);
return false;
}
}
return true;
}
public async Task<bool> tryDeleteFile(string bucketName, string s3Key)
{
var request = new DeleteObjectRequest
{
BucketName = bucketName,
Key = s3Key,
};
if (false == await deleteFile(request))
{
var err_msg = $"Failed to deleteFile() !!!, in tryDeleteFile() : bucketName:{bucketName}, s3Key:{s3Key}";
Log.getLogger().error(err_msg);
return false;
}
return true;
}
public async Task<bool> tryDeleteFolderFile(string bucketName, string prefix)
{
var request = new ListObjectsV2Request
{
BucketName = bucketName,
Prefix = prefix,
};
if (false == await deleteFolderFile(request))
{
var err_msg = $"Failed to deleteFolderFile() !!!, in tryDeleteFolderFile() : bucketName:{bucketName}, prefix:{prefix}";
Log.getLogger().error(err_msg);
return false;
}
return true;
}
public async Task<(bool, string)> tryGetFileData(string bucketName, string s3Key)
{
var request = new GetObjectRequest
{
BucketName = bucketName,
Key = s3Key,
};
(var is_success, var stream) = await getFileStream(request);
if (false == is_success)
{
var err_msg = $"Failed to getFile() !!! - bucketName:{bucketName}, s3Key:{s3Key}";
Log.getLogger().error(err_msg);
return (false, string.Empty);
}
NullReferenceCheckHelper.throwIfNull(stream, () => $"stream is null !!! - bucketName:{bucketName}, s3Key:{s3Key}");
return (true, stream.toString());
}
public async Task<(bool, string)> getPresignedUrl( string bucketName, string s3Key
, HttpVerb verbType, DateTime toExpireTime )
{
var err_msg = string.Empty;
var request = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Key = s3Key,
Verb = verbType,
Expires = toExpireTime
};
(var is_success, var presigned_url) = await generatePreSignedUrl(request);
if(false == is_success)
{
err_msg = $"Failed to generatePreSignedUrl() !!! : bucketName:{bucketName}, s3Key:{s3Key}, httpVerbType:{verbType}, toExpireTime:{toExpireTime.toStringWithUtcIso8601()}";
Log.getLogger().error(err_msg);
return (false, presigned_url);
}
return (true, presigned_url);
}
public AmazonS3Client? getAmazonS3Client() => m_s3_client;
public string toBasicString()
{
return $"{this.getTypeName()}, AccessKey:{m_access_key}, SecretKey:{m_secret_key}, Region:{m_region}";
}
}