using Amazon.S3; using Amazon.S3.Model; using FictionArchive.Common.Enums; using FictionArchive.Service.FileService.Contracts; using FictionArchive.Service.FileService.Models; using FictionArchive.Service.Shared.Contracts.Events; using MassTransit; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace FictionArchive.Service.FileService.Consumers; public class FileUploadRequestCreatedConsumer : IConsumer { private readonly ILogger _logger; private readonly AmazonS3Client _amazonS3Client; private readonly IPublishEndpoint _publishEndpoint; private readonly S3Configuration _s3Configuration; private readonly ProxyConfiguration _proxyConfiguration; public FileUploadRequestCreatedConsumer( ILogger logger, AmazonS3Client amazonS3Client, IPublishEndpoint publishEndpoint, IOptions s3Configuration, IOptions proxyConfiguration) { _logger = logger; _amazonS3Client = amazonS3Client; _publishEndpoint = publishEndpoint; _s3Configuration = s3Configuration.Value; _proxyConfiguration = proxyConfiguration.Value; } public async Task Consume(ConsumeContext context) { var message = context.Message; var putObjectRequest = new PutObjectRequest { BucketName = _s3Configuration.Bucket, Key = message.FilePath }; using var memoryStream = new MemoryStream(message.FileData); putObjectRequest.InputStream = memoryStream; var s3Response = await _amazonS3Client.PutObjectAsync(putObjectRequest); if (s3Response.HttpStatusCode != System.Net.HttpStatusCode.OK) { _logger.LogError("Failed to upload file {FilePath} to S3", message.FilePath); await _publishEndpoint.Publish( new FileUploadRequestStatusUpdate( RequestId: message.RequestId, Status: RequestStatus.Failed, FileAccessUrl: null, ErrorMessage: "An error occurred while uploading file to S3.")); return; } var fileAccessUrl = _proxyConfiguration.BaseUrl + "/" + message.FilePath; _logger.LogInformation("Successfully uploaded file {FilePath} to S3", message.FilePath); await _publishEndpoint.Publish( new FileUploadRequestStatusUpdate( RequestId: message.RequestId, Status: RequestStatus.Success, FileAccessUrl: fileAccessUrl, ErrorMessage: null)); } }