Changes on routes

This commit is contained in:
2026-03-27 21:16:38 +01:00
parent 9b1ae1a7a1
commit 075ff3c7b6
13 changed files with 92 additions and 60 deletions
@@ -8,6 +8,8 @@ namespace Musify.Application.Contracts.Infrastructure
Task<string> GetUrlAsync(string bucketName, string keyName, TimeSpan ExpirationTime, CancellationToken cancellationToken);
Task<Result<string>> UploadFileAsync(string filePath, string bucketName, string keyName, CancellationToken cancellationToken);
Task<Result<string>> UploadFileAsync(Stream sourceStream, string contentType, string bucketName, string keyName, CancellationToken cancellationToken);
Task<Result> TransferFilesAsync(string sourceDirectory, string bucketName, string route, CancellationToken cancellationToken);
@@ -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);
}
@@ -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<CreateTrackCommandHandler> logger, ApplicationStorageConfiguration storageConfiguration, TrackConfiguration trackConfiguration)
: IRequestHandler<CreateTrackCommand, Task<Result<TrackResponse> >>
{
@@ -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(
+1
View File
@@ -21,6 +21,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="10.0.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
<PackageReference Include="MimeMapping" Version="4.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.15.0" />
@@ -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<string>(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)
{
@@ -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)
{
@@ -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);
}
@@ -2,7 +2,6 @@
{
public record UploadFileToBucketArguments(
string FilePathVariableName,
string ContentType,
string DestinationBucketName,
string DestinationKeyName);
string DestinationRoute);
}
@@ -182,14 +182,14 @@ namespace Musify.Infrastructure.MassTransit
where TLog : class
{
busFactoryConfigurator.ReceiveEndpoint($"{endpointName}_execute", endpointConfigurator =>
{
endpointConfigurator.ExecuteActivityHost<TActivity, TArguments>(busRegistrationContext);
} );
endpointConfigurator.ExecuteActivityHost<TActivity, TArguments>(
MessagingHelper.BuildCompensateActivityUri(endpointName),
busRegistrationContext)
);
busFactoryConfigurator.ReceiveEndpoint($"{endpointName}_compensate", endpointConfigurator =>
{
endpointConfigurator.CompensateActivityHost<TActivity, TLog>(busRegistrationContext);
} );
endpointConfigurator.CompensateActivityHost<TActivity, TLog>(busRegistrationContext)
);
}
}
}
@@ -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";
@@ -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));
}
}
}
@@ -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";
}
}
}
+16
View File
@@ -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<Result<string>> 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<Result<string>> UploadFileAsync(Stream sourceStream, string contentType, string bucketName, string keyName, CancellationToken cancellationToken)
{
var request = new PutObjectRequest