From 0c04ddf3163c14fa32e91bc97d3398f239fc4364 Mon Sep 17 00:00:00 2001 From: XShine555 Date: Thu, 19 Mar 2026 01:20:05 +0100 Subject: [PATCH] Remove files consumer --- .../CreatePlayListCommandHandler.cs | 11 ++--- .../DeletePlayListCommandHandler.cs | 29 ++++++++++--- Domain/Entities/PlayList.cs | 4 ++ .../Messaging/Consumers/RemoveFileConsumer.cs | 42 +++++++++++++++++-- .../MassTransitDependencyInjection.cs | 5 +++ 5 files changed, 78 insertions(+), 13 deletions(-) diff --git a/Application/PlayLists/Commands/CreatePlayList/CreatePlayListCommandHandler.cs b/Application/PlayLists/Commands/CreatePlayList/CreatePlayListCommandHandler.cs index d47cd82..8ff6c82 100644 --- a/Application/PlayLists/Commands/CreatePlayList/CreatePlayListCommandHandler.cs +++ b/Application/PlayLists/Commands/CreatePlayList/CreatePlayListCommandHandler.cs @@ -25,20 +25,21 @@ namespace Musify.Application.PlayLists.Commands.CreatePlayList return Result.NotFound($"User with Id {request.UserId} does not exist."); } + var imageId = Guid.NewGuid(); + var playList = new PlayList { UserId = request.UserId, Name = request.Name, NormalizedName = request.Name.Trim().ToUpperInvariant(), Description = request.Description, - SmallPictureKeyName = playListConfiguration.Routes.SmallPictures, - MediumPictureKeyName = playListConfiguration.Routes.MediumPictures, - LargePictureKeyName = playListConfiguration.Routes.LargePictures, + OriginalPictureKeyName = $"{imageId}/{request.PictureFileType}", + SmallPictureKeyName = playListConfiguration.Routes.PresetSmallPicture, + MediumPictureKeyName = playListConfiguration.Routes.PresetMediumPicture, + LargePictureKeyName = playListConfiguration.Routes.PresetLargePicture, }; await database.PlayLists.AddAsync(playList, cancellationToken); - var imageId = Guid.NewGuid(); - var imageKeyName = $"{playListConfiguration.Routes.OriginalPictures}/{imageId}.{request.PictureFileType}"; var uploadResult = await storageHandler.UploadFileAsync( diff --git a/Application/PlayLists/Commands/DeletePlayList/DeletePlayListCommandHandler.cs b/Application/PlayLists/Commands/DeletePlayList/DeletePlayListCommandHandler.cs index e7ca9b7..5738e15 100644 --- a/Application/PlayLists/Commands/DeletePlayList/DeletePlayListCommandHandler.cs +++ b/Application/PlayLists/Commands/DeletePlayList/DeletePlayListCommandHandler.cs @@ -1,13 +1,15 @@ using Ardalis.Result; using DispatchR.Abstractions.Send; +using MassTransit; using Microsoft.Extensions.Logging; using Musify.Application.Configuration; using Musify.Application.Contracts.Infrastructure; +using Musify.Application.Events; namespace Musify.Application.PlayLists.Commands.DeletePlayList { - public class DeletePlayListCommandHandler(IDatabase database, IStorageHandler storageHandler, - StorageConfiguration storageConfiguration, ILogger logger) + public class DeletePlayListCommandHandler(IDatabase database, IPublishEndpoint publishEndpoint, + StorageConfiguration storageConfiguration, PlayListConfiguration playListConfiguration, ILogger logger) : IRequestHandler> { public async Task Handle(DeletePlayListCommand request, CancellationToken cancellationToken) @@ -26,11 +28,28 @@ namespace Musify.Application.PlayLists.Commands.DeletePlayList return Result.Unauthorized(); } + await publishEndpoint.Publish(new RemoveFileEvent( + storageConfiguration.BucketName, + playList.OriginalPictureKeyName), cancellationToken); + + if (playList.SmallPictureKeyName != playListConfiguration.Routes.PresetSmallPicture) + await publishEndpoint.Publish(new RemoveFileEvent( + storageConfiguration.BucketName, + playList.SmallPictureKeyName), cancellationToken); + + if (playList.MediumPictureKeyName != playListConfiguration.Routes.PresetMediumPicture) + await publishEndpoint.Publish(new RemoveFileEvent( + storageConfiguration.BucketName, + playList.MediumPictureKeyName), cancellationToken); + + if (playList.LargePictureKeyName != playListConfiguration.Routes.PresetLargePicture) + await publishEndpoint.Publish(new RemoveFileEvent( + storageConfiguration.BucketName, + playList.LargePictureKeyName), cancellationToken); + database.PlayLists.Remove(playList); - await database.SaveChangesAsync(cancellationToken); - return Result.NoContent(); } } -} +} \ No newline at end of file diff --git a/Domain/Entities/PlayList.cs b/Domain/Entities/PlayList.cs index 44d751f..876854e 100644 --- a/Domain/Entities/PlayList.cs +++ b/Domain/Entities/PlayList.cs @@ -25,6 +25,10 @@ namespace Musify.Domain.Entities [MaxLength(254)] public required string Description { get; set; } = "No description was provided."; + [Required] + [MaxLength(64)] + public required string OriginalPictureKeyName { get; set; } + [Required] [MaxLength(64)] public required string SmallPictureKeyName { get; set; } diff --git a/Infrastructure/Messaging/Consumers/RemoveFileConsumer.cs b/Infrastructure/Messaging/Consumers/RemoveFileConsumer.cs index 29b4244..ce79d4f 100644 --- a/Infrastructure/Messaging/Consumers/RemoveFileConsumer.cs +++ b/Infrastructure/Messaging/Consumers/RemoveFileConsumer.cs @@ -1,14 +1,50 @@ using MassTransit; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Musify.Application.Contracts.Infrastructure; using Musify.Application.Events; +using Musify.Domain.Entities; +using System.Text.Json; namespace Musify.Infrastructure.Messaging.Consumers { - public class RemoveFileConsumer + public class RemoveFileConsumer(IDatabase database, IStorageHandler storageHandler, ILogger logger) : IConsumer { - public Task Consume(ConsumeContext context) + public const string QueueName = "file-remove-queue"; + + public async Task Consume(ConsumeContext consumeContext) { - throw new NotImplementedException(); + var payload = JsonSerializer.Serialize(consumeContext.Message); + + var job = await database.Jobs + .SingleOrDefaultAsync(j => j.JobState == JobState.Failed && j.Payload == payload); + + if (job is null) + { + job = new Job + { + JobType = JobType.RemoveFile, + Payload = payload + }; + await database.Jobs.AddAsync(job, consumeContext.CancellationToken); + } + else + { + job.RetryCount++; + job.JobState = JobState.Pending; + database.Jobs.Update(job); + } + + var removeFile = await storageHandler.RemoveFileAsync( + consumeContext.Message.BucketName, + consumeContext.Message.KeyName, + consumeContext.CancellationToken); + + if (!removeFile.IsSuccess) + job.JobState = JobState.Failed; + + await database.SaveChangesAsync(consumeContext.CancellationToken); } } } \ No newline at end of file diff --git a/Infrastructure/Messaging/MassTransitDependencyInjection.cs b/Infrastructure/Messaging/MassTransitDependencyInjection.cs index a38f593..3d7cf60 100644 --- a/Infrastructure/Messaging/MassTransitDependencyInjection.cs +++ b/Infrastructure/Messaging/MassTransitDependencyInjection.cs @@ -38,6 +38,7 @@ namespace Musify.Infrastructure.Messaging serviceDescriptors.AddMassTransit(options => { options.AddConsumer(); + options.AddConsumer(); options.UsingRabbitMq((busRegistrationContext, busFactoryConfigurator) => { @@ -62,6 +63,10 @@ namespace Musify.Infrastructure.Messaging { endpointConfigurator.ConfigureConsumer(busRegistrationContext); } ); + busFactoryConfigurator.ReceiveEndpoint(RemoveFileConsumer.QueueName, endpointConfigurator => + { + endpointConfigurator.ConfigureConsumer(busRegistrationContext); + } ); } ); } ); }