72 lines
2.6 KiB
C#
72 lines
2.6 KiB
C#
using Microsoft.Extensions.Logging;
|
|||
|
|
using mws.backend.dotnet.application.Common;
|
||
|
|
using mws.backend.dotnet.application.Documents;
|
||
|
|
|
||
|
|
namespace mws.backend.dotnet.infrastructure.CloudFile;
|
||
|
|
|
||
|
|
public class CloudFileDocumentContentStore(
|
||
|
|
ICloudFileHttpClient cf,
|
||
|
|
ILogger<CloudFileDocumentContentStore> log) : IDocumentContentStore
|
||
|
|
{
|
||
|
|
private static string Bucket(Guid projectId) => $"mws-p-{projectId:N}";
|
||
|
|
private static string Key(Guid documentId) => $"{documentId:N}.html";
|
||
|
|
|
||
|
|
public Task EnsureBucketAsync(Guid projectId, CancellationToken ct) =>
|
||
|
|
cf.EnsureBucketAsync(Bucket(projectId), ct);
|
||
|
|
|
||
|
|
public async Task UploadAsync(Guid projectId, Guid documentId, string contentType, Stream body, CancellationToken ct)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var meta = await cf.UploadAsync(Bucket(projectId), Key(documentId), contentType, body, ct);
|
||
|
|
log.LogDebug("Uploaded document {DocumentId} to cloudfile: {Hash}", documentId, meta?.ContentHash);
|
||
|
|
}
|
||
|
|
catch (HttpRequestException ex)
|
||
|
|
{
|
||
|
|
log.LogError(ex, "CloudFile upload failed for document {DocumentId}", documentId);
|
||
|
|
throw new StorageUnavailableException("Cloud file upload failed", ex);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<Stream> DownloadAsync(Guid projectId, Guid documentId, CancellationToken ct)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
return await cf.DownloadAsync(Bucket(projectId), Key(documentId), ct);
|
||
|
|
}
|
||
|
|
catch (HttpRequestException ex)
|
||
|
|
{
|
||
|
|
log.LogError(ex, "CloudFile download failed for document {DocumentId}", documentId);
|
||
|
|
throw new StorageUnavailableException("Cloud file download failed", ex);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<bool> ExistsAsync(Guid projectId, Guid documentId, CancellationToken ct)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
return await cf.ExistsAsync(Bucket(projectId), Key(documentId), ct);
|
||
|
|
}
|
||
|
|
catch (HttpRequestException)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task DeleteAsync(Guid projectId, Guid documentId, CancellationToken ct)
|
||
|
|
{
|
||
|
|
var bucket = Bucket(projectId);
|
||
|
|
var key = Key(documentId);
|
||
|
|
log.LogInformation("CloudFile delete: bucket={Bucket}, key={Key}", bucket, key);
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await cf.DeleteAsync(bucket, key, ct);
|
||
|
|
log.LogInformation("CloudFile delete OK for document {DocumentId}", documentId);
|
||
|
|
}
|
||
|
|
catch (HttpRequestException ex)
|
||
|
|
{
|
||
|
|
log.LogWarning(ex, "CloudFile delete failed for document {DocumentId} (bucket={Bucket}, key={Key})", documentId, bucket, key);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|