From 8e678435f4102d9cab6abf8086b4d438ceff6ecd Mon Sep 17 00:00:00 2001 From: NotS1mp Date: Fri, 27 Mar 2026 21:16:38 +0100 Subject: [PATCH] Changes on routes --- .../Infrastructure/IStorageHandler.cs | 2 + Application/Events/UpdateTrackPictureEvent.cs | 6 +- .../Handler/CreateTrackCommandHandler.cs | 21 +++---- Infrastructure/Infrastructure.csproj | 1 + .../Files/UploadFileToBucketActivity.cs | 15 +++-- .../Pictures/ResizePictureActivity.cs | 5 +- .../GeneratePictureWorkflowPathsArguments.cs | 7 +-- .../Arguments/UploadFileToBucketArguments.cs | 3 +- .../MessagingDependencyInjection.cs | 12 ++-- .../MassTransit/RoutingSlip/ActivityNames.cs | 4 +- .../PictureWorkflowRoutingSlipBuilder.cs | 56 +++++++++++++------ .../Variables/RoutingSlipVariableNames.cs | 4 ++ Infrastructure/Storage/StorageHandler.cs | 16 ++++++ 13 files changed, 92 insertions(+), 60 deletions(-) diff --git a/Application/Contracts/Infrastructure/IStorageHandler.cs b/Application/Contracts/Infrastructure/IStorageHandler.cs index c247c88..3056fab 100644 --- a/Application/Contracts/Infrastructure/IStorageHandler.cs +++ b/Application/Contracts/Infrastructure/IStorageHandler.cs @@ -8,6 +8,8 @@ namespace Musify.Application.Contracts.Infrastructure Task GetUrlAsync(string bucketName, string keyName, TimeSpan ExpirationTime, CancellationToken cancellationToken); + Task> UploadFileAsync(string filePath, string bucketName, string keyName, CancellationToken cancellationToken); + Task> UploadFileAsync(Stream sourceStream, string contentType, string bucketName, string keyName, CancellationToken cancellationToken); Task TransferFilesAsync(string sourceDirectory, string bucketName, string route, CancellationToken cancellationToken); diff --git a/Application/Events/UpdateTrackPictureEvent.cs b/Application/Events/UpdateTrackPictureEvent.cs index 1ba00be..b9ae6e7 100644 --- a/Application/Events/UpdateTrackPictureEvent.cs +++ b/Application/Events/UpdateTrackPictureEvent.cs @@ -4,13 +4,13 @@ Guid TrackId, string SourceBucketName, string SourceKeyName, - string SmallPictureKeyName, + string SmallPictureRoute, int SmallPictureWidth, int SmallPictureHeight, - string MediumPictureKeyName, + string MediumPictureRoute, int MediumPictureWidth, int MediumPictureHeight, - string LargePictureKeyName, + string LargePictureRoute, int LargePictureWidth, int LargePictureHeight); } \ No newline at end of file diff --git a/Application/Tracks/Handler/CreateTrackCommandHandler.cs b/Application/Tracks/Handler/CreateTrackCommandHandler.cs index f683fe4..b7c8220 100644 --- a/Application/Tracks/Handler/CreateTrackCommandHandler.cs +++ b/Application/Tracks/Handler/CreateTrackCommandHandler.cs @@ -11,7 +11,7 @@ using Musify.Domain.Entities; namespace Musify.Application.Tracks.Handler { - public class CreateTrackCommandHandler(IDatabase database, IPictureHandler pictureHandler, IEventBus eventBus, IStorageHandler storageHandler, + public class CreateTrackCommandHandler(IDatabase database, IEventBus eventBus, IStorageHandler storageHandler, ILogger logger, ApplicationStorageConfiguration storageConfiguration, TrackConfiguration trackConfiguration) : IRequestHandler >> { @@ -38,7 +38,7 @@ namespace Musify.Application.Tracks.Handler LargePictureKeyName = trackConfiguration.Routes.PresetLargePicture, }; - var originalPictureKeyName = Path.Combine(trackConfiguration.Routes.PresetMediumPicture, + var originalPictureKeyName = Path.Combine(trackConfiguration.Routes.OriginalPicturesPath, originalPictureFileName); var pictureUploadResult = await UploadFile(request.Picture, originalPictureKeyName, cancellationToken); if (!pictureUploadResult.IsSuccess) @@ -48,7 +48,7 @@ namespace Musify.Application.Tracks.Handler } - var audioKeyName = Path.Combine(trackConfiguration.Routes.OriginalAudiosFolder, + var audioKeyName = Path.Combine(trackConfiguration.Routes.OriginalAudiosPath, Guid.NewGuid() + request.Audio.FileType); var audioUploadResult = await UploadFile(request.Audio, audioKeyName, cancellationToken); if (!audioUploadResult.IsSuccess) @@ -97,31 +97,24 @@ namespace Musify.Application.Tracks.Handler async Task PublishUpdateEvent(string originalPictureKeyName, Track track, CancellationToken cancellationToken) { - var smallPictureKeyName = Path.Combine(trackConfiguration.Routes.MediumPicturesPath, - track.Id + pictureHandler.FileExtension); - var mediumPictureKeyName = Path.Combine(trackConfiguration.Routes.MediumPicturesPath, - track.Id + pictureHandler.FileExtension); - var largePictureKeyName = Path.Combine(trackConfiguration.Routes.LargePicturesPath, - track.Id + pictureHandler.FileExtension); - await eventBus.PublishAsync(new UpdateTrackPictureEvent( track.Id, storageConfiguration.BucketName, originalPictureKeyName, - smallPictureKeyName, + trackConfiguration.Routes.SmallPicturesPath, trackConfiguration.PicturesSizes.SmallPictureWidth, trackConfiguration.PicturesSizes.SmallPictureHeight, - mediumPictureKeyName, + trackConfiguration.Routes.MediumPicturesPath, trackConfiguration.PicturesSizes.MediumPictureWidth, trackConfiguration.PicturesSizes.MediumPictureHeight, - largePictureKeyName, + trackConfiguration.Routes.LargePicturesPath, trackConfiguration.PicturesSizes.LargePictureWidth, trackConfiguration.PicturesSizes.LargePictureHeight), cancellationToken); } async Task PublishTranscodeEvent(Guid trackId, string audioKeyName, CancellationToken cancellationToken) { - var destinationFolderAudio = Path.Combine(trackConfiguration.Routes.ProcessedAudioFolder, + var destinationFolderAudio = Path.Combine(trackConfiguration.Routes.ProcessedAudiosPath, Guid.NewGuid().ToString()); await eventBus.PublishAsync(new UpdateTrackAudioEvent( diff --git a/Infrastructure/Infrastructure.csproj b/Infrastructure/Infrastructure.csproj index 256cc80..85e8989 100644 --- a/Infrastructure/Infrastructure.csproj +++ b/Infrastructure/Infrastructure.csproj @@ -21,6 +21,7 @@ + diff --git a/Infrastructure/MassTransit/Activities/Files/UploadFileToBucketActivity.cs b/Infrastructure/MassTransit/Activities/Files/UploadFileToBucketActivity.cs index 4f20d49..da16d42 100644 --- a/Infrastructure/MassTransit/Activities/Files/UploadFileToBucketActivity.cs +++ b/Infrastructure/MassTransit/Activities/Files/UploadFileToBucketActivity.cs @@ -1,5 +1,6 @@ using MassTransit; using Microsoft.Extensions.Logging; +using MimeMapping; using Musify.Application.Contracts.Infrastructure; using Musify.Domain.Entities; using Musify.Infrastructure.MassTransit.Arguments; @@ -33,16 +34,14 @@ namespace Musify.Infrastructure.MassTransit.Activities.Files var sourceFilePath = executeContext.GetVariable(executeContext.Arguments.FilePathVariableName); if (string.IsNullOrEmpty(sourceFilePath)) throw new InvalidOperationException($"Upload activity requires variable '{executeContext.Arguments.FilePathVariableName}' with source file path."); + var fileName = Path.GetFileName(sourceFilePath); try { - using var fileStream = File.OpenRead(sourceFilePath); - var uploadResult = await storageHandler.UploadFileAsync( - fileStream, - executeContext.Arguments.ContentType, + sourceFilePath, executeContext.Arguments.DestinationBucketName, - executeContext.Arguments.DestinationKeyName, + Path.Combine(executeContext.Arguments.DestinationRoute, fileName), executeContext.CancellationToken); if (!uploadResult.IsSuccess) @@ -50,15 +49,15 @@ namespace Musify.Infrastructure.MassTransit.Activities.Files var errors = string.Join("; ", uploadResult.Errors); logger.LogWarning("Failed to upload file to bucket. Bucket: {BucketName}, Key: {KeyName}, Errors: {Errors}", executeContext.Arguments.DestinationBucketName, - executeContext.Arguments.DestinationKeyName, + executeContext.Arguments.DestinationRoute, errors); throw new Exception(errors); } await processTrackingStore.CompleteStepAsync(processId, stepId, executeContext.CancellationToken); - return executeContext.Completed(new UploadFileToBucketLog( + return executeContext.CompletedWithVariables(new UploadFileToBucketLog( executeContext.Arguments.DestinationBucketName, - executeContext.Arguments.DestinationKeyName)); + executeContext.Arguments.DestinationRoute)); } catch (Exception exception) { diff --git a/Infrastructure/MassTransit/Activities/Pictures/ResizePictureActivity.cs b/Infrastructure/MassTransit/Activities/Pictures/ResizePictureActivity.cs index adbcb5b..461da5a 100644 --- a/Infrastructure/MassTransit/Activities/Pictures/ResizePictureActivity.cs +++ b/Infrastructure/MassTransit/Activities/Pictures/ResizePictureActivity.cs @@ -4,6 +4,7 @@ using Musify.Application.Contracts.Infrastructure; using Musify.Domain.Entities; using Musify.Infrastructure.MassTransit.Activities.Arguments; using Musify.Infrastructure.MassTransit.Activities.Logs; +using Musify.Infrastructure.MassTransit.RoutingSlip.Builders; namespace Musify.Infrastructure.MassTransit.Activities { @@ -66,9 +67,7 @@ namespace Musify.Infrastructure.MassTransit.Activities var destinationDirectory = Path.GetDirectoryName(destinationFilePath); if (!string.IsNullOrEmpty(destinationDirectory)) - { Directory.CreateDirectory(destinationDirectory); - } await using var destinationStream = File.Create(destinationFilePath); await resizedPicture.Value.CopyToAsync(destinationStream, executeContext.CancellationToken); @@ -80,7 +79,7 @@ namespace Musify.Infrastructure.MassTransit.Activities executeContext.Arguments.Height); await processTrackingStore.CompleteStepAsync(processId, stepId, executeContext.CancellationToken); - return executeContext.Completed(); + return executeContext.Completed(new ResizePictureLog(destinationFilePath)); } catch (Exception exception) { diff --git a/Infrastructure/MassTransit/Arguments/GeneratePictureWorkflowPathsArguments.cs b/Infrastructure/MassTransit/Arguments/GeneratePictureWorkflowPathsArguments.cs index ad6fc1c..2460135 100644 --- a/Infrastructure/MassTransit/Arguments/GeneratePictureWorkflowPathsArguments.cs +++ b/Infrastructure/MassTransit/Arguments/GeneratePictureWorkflowPathsArguments.cs @@ -2,8 +2,5 @@ namespace Musify.Infrastructure.MassTransit.Activities.Arguments { public record GeneratePictureWorkflowPathsArguments( string TemporaryRootDirectory, - string SourceKeyName, - string SmallPictureKeyName, - string MediumPictureKeyName, - string LargePictureKeyName); -} + string SourceKeyName); +} \ No newline at end of file diff --git a/Infrastructure/MassTransit/Arguments/UploadFileToBucketArguments.cs b/Infrastructure/MassTransit/Arguments/UploadFileToBucketArguments.cs index ab6ccda..9d01163 100644 --- a/Infrastructure/MassTransit/Arguments/UploadFileToBucketArguments.cs +++ b/Infrastructure/MassTransit/Arguments/UploadFileToBucketArguments.cs @@ -2,7 +2,6 @@ { public record UploadFileToBucketArguments( string FilePathVariableName, - string ContentType, string DestinationBucketName, - string DestinationKeyName); + string DestinationRoute); } \ No newline at end of file diff --git a/Infrastructure/MassTransit/DependencyInjection/MessagingDependencyInjection.cs b/Infrastructure/MassTransit/DependencyInjection/MessagingDependencyInjection.cs index af7b44c..1406c5b 100644 --- a/Infrastructure/MassTransit/DependencyInjection/MessagingDependencyInjection.cs +++ b/Infrastructure/MassTransit/DependencyInjection/MessagingDependencyInjection.cs @@ -182,14 +182,14 @@ namespace Musify.Infrastructure.MassTransit where TLog : class { busFactoryConfigurator.ReceiveEndpoint($"{endpointName}_execute", endpointConfigurator => - { - endpointConfigurator.ExecuteActivityHost(busRegistrationContext); - } ); + endpointConfigurator.ExecuteActivityHost( + MessagingHelper.BuildCompensateActivityUri(endpointName), + busRegistrationContext) + ); busFactoryConfigurator.ReceiveEndpoint($"{endpointName}_compensate", endpointConfigurator => - { - endpointConfigurator.CompensateActivityHost(busRegistrationContext); - } ); + endpointConfigurator.CompensateActivityHost(busRegistrationContext) + ); } } } \ No newline at end of file diff --git a/Infrastructure/MassTransit/RoutingSlip/ActivityNames.cs b/Infrastructure/MassTransit/RoutingSlip/ActivityNames.cs index 3b6d6cf..85033b7 100644 --- a/Infrastructure/MassTransit/RoutingSlip/ActivityNames.cs +++ b/Infrastructure/MassTransit/RoutingSlip/ActivityNames.cs @@ -9,8 +9,10 @@ namespace Musify.Infrastructure.MassTransit.RoutingSlip internal const string ResizeSmall = "ResizeSmall"; internal const string ResizeMedium = "ResizeMedium"; internal const string ResizeLarge = "ResizeLarge"; + internal const string UploadSmall = "UploadSmall"; + internal const string UploadMedium = "UploadMedium"; + internal const string UploadLarge = "UploadLarge"; internal const string TransferFiles = "TransferFiles"; - internal const string UploadFiles = "UploadFiles"; internal const string RemoveFile = "RemoveFile"; internal const string DeleteOriginal = "DeleteOriginal"; internal const string UpdateTrackPicture = "UpdateTrackPicture"; diff --git a/Infrastructure/MassTransit/RoutingSlip/Builders/PictureWorkflowRoutingSlipBuilder.cs b/Infrastructure/MassTransit/RoutingSlip/Builders/PictureWorkflowRoutingSlipBuilder.cs index 1c4043c..5ddc032 100644 --- a/Infrastructure/MassTransit/RoutingSlip/Builders/PictureWorkflowRoutingSlipBuilder.cs +++ b/Infrastructure/MassTransit/RoutingSlip/Builders/PictureWorkflowRoutingSlipBuilder.cs @@ -1,10 +1,13 @@ using MassTransit; using MassTransit.Courier.Contracts; +using MimeMapping; using Musify.Application.Events; using Musify.Infrastructure.Configuration; -using Musify.Infrastructure.MassTransit.Consumers; using Musify.Infrastructure.MassTransit.Activities; using Musify.Infrastructure.MassTransit.Activities.Arguments; +using Musify.Infrastructure.MassTransit.Activities.Files; +using Musify.Infrastructure.MassTransit.Arguments; +using Musify.Infrastructure.MassTransit.Consumers; namespace Musify.Infrastructure.MassTransit.RoutingSlip.Builders { @@ -15,13 +18,13 @@ namespace Musify.Infrastructure.MassTransit.RoutingSlip.Builders var routingSlipBuilder = BuildPictureWorkflow( message.SourceBucketName, message.SourceKeyName, - message.SmallPictureKeyName, + message.SmallPictureRoute, message.SmallPictureWidth, message.SmallPictureHeight, - message.MediumPictureKeyName, + message.MediumPictureRoute, message.MediumPictureWidth, message.MediumPictureHeight, - message.LargePictureKeyName, + message.LargePictureRoute, message.LargePictureWidth, message.LargePictureHeight, correlationId); @@ -36,9 +39,9 @@ namespace Musify.Infrastructure.MassTransit.RoutingSlip.Builders new UpdateTrackPictureArguments( message.TrackId, message.SourceKeyName, - message.SmallPictureKeyName, - message.MediumPictureKeyName, - message.LargePictureKeyName)); + message.SmallPictureRoute, + message.MediumPictureRoute, + message.LargePictureRoute)); return routingSlipBuilder; } @@ -73,15 +76,15 @@ namespace Musify.Infrastructure.MassTransit.RoutingSlip.Builders } RoutingSlipBuilder BuildPictureWorkflow( - string sourceBucketName, + string bucketName, string sourceKeyName, - string smallPictureKeyName, + string destinationSmallPictureRoute, int smallPictureWidth, int smallPictureHeight, - string mediumPictureKeyName, + string destinationMediumPictureRoute, int mediumPictureWidth, int mediumPictureHeight, - string largePictureKeyName, + string destinationLargePictureRoute, int largePictureWidth, int largePictureHeight, Guid? correlationId) @@ -95,37 +98,43 @@ namespace Musify.Infrastructure.MassTransit.RoutingSlip.Builders MessagingHelper.BuildExecuteActivityUri(GeneratePictureWorkflowPathsActivity.ExecuteEndpointName), new GeneratePictureWorkflowPathsArguments( workerConfiguration.Routes.TemporaryFilesDirectory, - sourceKeyName, - smallPictureKeyName, - mediumPictureKeyName, - largePictureKeyName)); + sourceKeyName)); routingSlipBuilder.AddActivity( ActivityNames.DownloadFile, MessagingHelper.BuildExecuteActivityUri(DownloadFileFromBucketActivity.ExecuteEndpointName), new DownloadFileFromBucketArguments( - sourceBucketName, + bucketName, sourceKeyName, RoutingSlipVariableNames.Picture.OriginalFilePath)); AddResizeActivity( routingSlipBuilder, ActivityNames.ResizeSmall, + ActivityNames.UploadSmall, + bucketName, RoutingSlipVariableNames.Picture.SmallResizedFilePath, + destinationSmallPictureRoute, smallPictureWidth, smallPictureHeight); AddResizeActivity( routingSlipBuilder, ActivityNames.ResizeMedium, + ActivityNames.ResizeMedium, + bucketName, RoutingSlipVariableNames.Picture.MediumResizedFilePath, + destinationMediumPictureRoute, mediumPictureWidth, mediumPictureHeight); AddResizeActivity( routingSlipBuilder, ActivityNames.ResizeLarge, + ActivityNames.UploadLarge, + bucketName, RoutingSlipVariableNames.Picture.LargeResizedFilePath, + destinationLargePictureRoute, largePictureWidth, largePictureHeight); @@ -134,19 +143,30 @@ namespace Musify.Infrastructure.MassTransit.RoutingSlip.Builders static void AddResizeActivity( RoutingSlipBuilder routingSlipBuilder, - string activityName, + string resizeActivityName, + string uploadActivityName, + string bucketName, string destinationFilePathVariableName, + string destinationBucketRoute, int width, int height) { routingSlipBuilder.AddActivity( - activityName, + resizeActivityName, MessagingHelper.BuildExecuteActivityUri(ResizePictureActivity.ExecuteEndpointName), new ResizePictureLocalArguments( RoutingSlipVariableNames.Picture.OriginalFilePath, destinationFilePathVariableName, width, height)); + + routingSlipBuilder.AddActivity( + uploadActivityName, + MessagingHelper.BuildExecuteActivityUri(UploadFileToBucketActivity.ExecuteEndpointName), + new UploadFileToBucketArguments( + destinationFilePathVariableName, + bucketName, + destinationBucketRoute)); } } } diff --git a/Infrastructure/MassTransit/RoutingSlip/Variables/RoutingSlipVariableNames.cs b/Infrastructure/MassTransit/RoutingSlip/Variables/RoutingSlipVariableNames.cs index 8ffad05..f549121 100644 --- a/Infrastructure/MassTransit/RoutingSlip/Variables/RoutingSlipVariableNames.cs +++ b/Infrastructure/MassTransit/RoutingSlip/Variables/RoutingSlipVariableNames.cs @@ -22,6 +22,10 @@ namespace Musify.Infrastructure.MassTransit internal const string MediumResizedFilePath = "Picture.MediumResizedFilePath"; internal const string LargeResizedFilePath = "Picture.LargeResizedFilePath"; internal const string DestinationFolderName = "Picture.DestinationFolderName"; + + internal const string SmallPictureKeyName = "Picture.SmallPictureKeyName"; + internal const string MediumPictureKeyName = "Picture.MediumPictureKeyName"; + internal const string LargePictureKeyName = "Picture.LargePictureKeyName"; } } } diff --git a/Infrastructure/Storage/StorageHandler.cs b/Infrastructure/Storage/StorageHandler.cs index a61c822..44fce65 100644 --- a/Infrastructure/Storage/StorageHandler.cs +++ b/Infrastructure/Storage/StorageHandler.cs @@ -3,6 +3,7 @@ using Amazon.S3.Model; using Amazon.S3.Transfer; using Ardalis.Result; using Microsoft.Extensions.Logging; +using MimeMapping; using Musify.Application.Contracts.Infrastructure; using Musify.Domain.Entities; using Musify.Infrastructure.Configuration; @@ -111,6 +112,21 @@ namespace Musify.Infrastructure.Storage return Result.Success(); } + public async Task> UploadFileAsync(string filePath, string bucketName, string keyName, CancellationToken cancellationToken) + { + try + { + using var fileStream = File.OpenRead(filePath); + var contentType = MimeUtility.GetMimeMapping(filePath); + return await UploadFileAsync(fileStream, contentType, bucketName, keyName, cancellationToken); + } + catch (Exception exception) + { + logger.LogError(exception, "Failed to upload file to S3 with bucket name {BucketName} and key name {KeyName}", bucketName, keyName); + return Result.Error($"Failed to upload file to S3 with bucket name {bucketName} and key name {keyName}"); + } + } + public async Task> UploadFileAsync(Stream sourceStream, string contentType, string bucketName, string keyName, CancellationToken cancellationToken) { var request = new PutObjectRequest