Refactor
This commit is contained in:
@@ -11,8 +11,7 @@ namespace Musify.Infrastructure.Configuration
|
|||||||
serviceDescriptors
|
serviceDescriptors
|
||||||
.AddValidatedConfiguration<DatabaseConfiguration>(configuration, DatabaseConfiguration.SectionName)
|
.AddValidatedConfiguration<DatabaseConfiguration>(configuration, DatabaseConfiguration.SectionName)
|
||||||
.AddValidatedConfiguration<KeycloakConfiguration>(configuration, KeycloakConfiguration.SectionName)
|
.AddValidatedConfiguration<KeycloakConfiguration>(configuration, KeycloakConfiguration.SectionName)
|
||||||
.AddValidatedConfiguration<StorageClientConfiguration>(configuration, StorageClientConfiguration.SectionName)
|
.AddValidatedConfiguration<StorageClientConfiguration>(configuration, StorageClientConfiguration.SectionName);
|
||||||
.AddValidatedConfiguration<WorkerStorageConfiguration>(configuration, WorkerStorageConfiguration.SectionName);
|
|
||||||
|
|
||||||
return serviceDescriptors;
|
return serviceDescriptors;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Musify.Infrastructure.Configuration
|
|
||||||
{
|
|
||||||
public class WorkerStorageConfiguration
|
|
||||||
{
|
|
||||||
public const string SectionName = "WorkerStorage";
|
|
||||||
|
|
||||||
public Routes Routes { get; set; } = new Routes();
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[MinLength(3)]
|
|
||||||
public required string BucketName { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Routes
|
|
||||||
{
|
|
||||||
[Required]
|
|
||||||
public string TemporaryFiles { get; set; } = "TemporaryFiles";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,24 +6,27 @@ using Musify.Infrastructure.Messaging.Activities.Arguments;
|
|||||||
namespace Musify.Infrastructure.Messaging.Activities
|
namespace Musify.Infrastructure.Messaging.Activities
|
||||||
{
|
{
|
||||||
public class RemoveFilesActivity(IStorageHandler storageHandler, ILogger<RemoveFilesActivity> logger)
|
public class RemoveFilesActivity(IStorageHandler storageHandler, ILogger<RemoveFilesActivity> logger)
|
||||||
: IExecuteActivity<RemoveFileArguments[]>
|
: IExecuteActivity<RemoveFileArguments>
|
||||||
{
|
{
|
||||||
public async Task<ExecutionResult> Execute(ExecuteContext<RemoveFileArguments[]> executeContext)
|
public const string ExecuteEndpointName = "Remove-File";
|
||||||
{
|
|
||||||
foreach (var file in executeContext.Arguments)
|
|
||||||
{
|
|
||||||
var removeFile = await storageHandler.RemoveFileAsync(
|
|
||||||
file.BucketName,
|
|
||||||
file.KeyName,
|
|
||||||
executeContext.CancellationToken);
|
|
||||||
|
|
||||||
if (!removeFile.IsSuccess)
|
public async Task<ExecutionResult> Execute(ExecuteContext<RemoveFileArguments> executeContext)
|
||||||
{
|
{
|
||||||
string errorMessage = string.Join(";", removeFile.Errors);
|
var removeFile = await storageHandler.RemoveFileAsync(
|
||||||
logger.LogWarning("Failed to remove file {File} from bucket {BucketName}: {ErrorMessage}",
|
executeContext.Arguments.BucketName,
|
||||||
file, file.BucketName, errorMessage);
|
executeContext.Arguments.KeyName,
|
||||||
}
|
executeContext.CancellationToken);
|
||||||
|
|
||||||
|
if (!removeFile.IsSuccess)
|
||||||
|
{
|
||||||
|
string errorMessage = string.Join(";", removeFile.Errors);
|
||||||
|
logger.LogWarning(
|
||||||
|
"Failed to remove file {KeyName} from bucket {BucketName}: {ErrorMessage}",
|
||||||
|
executeContext.Arguments.KeyName,
|
||||||
|
executeContext.Arguments.BucketName,
|
||||||
|
errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return executeContext.Completed();
|
return executeContext.Completed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ namespace Musify.Infrastructure.Messaging.Activities
|
|||||||
public class ResizePictureActivity(IStorageHandler storageHandler, IPictureHandler pictureHandler)
|
public class ResizePictureActivity(IStorageHandler storageHandler, IPictureHandler pictureHandler)
|
||||||
: IExecuteActivity<ResizePictureArgument>
|
: IExecuteActivity<ResizePictureArgument>
|
||||||
{
|
{
|
||||||
|
public const string ExecuteEndpointName = "Resize-Picture";
|
||||||
|
|
||||||
public async Task<ExecutionResult> Execute(ExecuteContext<ResizePictureArgument> executeContext)
|
public async Task<ExecutionResult> Execute(ExecuteContext<ResizePictureArgument> executeContext)
|
||||||
{
|
{
|
||||||
var file = await storageHandler.GetFileAsync(
|
var file = await storageHandler.GetFileAsync(
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using MassTransit;
|
using MassTransit;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Contracts.Infrastructure;
|
using Musify.Application.Contracts.Infrastructure;
|
||||||
using Musify.Infrastructure.Messaging.Activities.Arguments;
|
using Musify.Infrastructure.Messaging.Activities.Arguments;
|
||||||
|
|
||||||
@@ -7,20 +8,21 @@ namespace Musify.Infrastructure.Messaging.Activities
|
|||||||
public class UpdatePlayListPictureActivity(IDatabase database)
|
public class UpdatePlayListPictureActivity(IDatabase database)
|
||||||
: IExecuteActivity<UpdatePlayListPictureArguments>
|
: IExecuteActivity<UpdatePlayListPictureArguments>
|
||||||
{
|
{
|
||||||
|
public const string ExecuteEndpointName = "Update-PlayList-Picture";
|
||||||
|
|
||||||
public async Task<ExecutionResult> Execute(ExecuteContext<UpdatePlayListPictureArguments> executeContext)
|
public async Task<ExecutionResult> Execute(ExecuteContext<UpdatePlayListPictureArguments> executeContext)
|
||||||
{
|
{
|
||||||
var PlayList = await database.PlayLists.FindAsync(executeContext.Arguments.PlayListId);
|
var playList = await database.PlayLists.SingleOrDefaultAsync(p => p.Id == executeContext.Arguments.PlayListId,
|
||||||
|
executeContext.CancellationToken);
|
||||||
|
|
||||||
if (PlayList is null)
|
if (playList is null)
|
||||||
{
|
|
||||||
throw new Exception($"PlayList with id {executeContext.Arguments.PlayListId} not found.");
|
throw new Exception($"PlayList with id {executeContext.Arguments.PlayListId} not found.");
|
||||||
}
|
|
||||||
|
|
||||||
PlayList.SmallPictureKeyName = executeContext.Arguments.SmallPictureKeyName;
|
playList.SmallPictureKeyName = executeContext.Arguments.SmallPictureKeyName;
|
||||||
PlayList.MediumPictureKeyName = executeContext.Arguments.MediumPictureKeyName;
|
playList.MediumPictureKeyName = executeContext.Arguments.MediumPictureKeyName;
|
||||||
PlayList.LargePictureKeyName = executeContext.Arguments.LargePictureKeyName;
|
playList.LargePictureKeyName = executeContext.Arguments.LargePictureKeyName;
|
||||||
|
|
||||||
database.PlayLists.Update(PlayList);
|
database.PlayLists.Update(playList);
|
||||||
await database.SaveChangesAsync(executeContext.CancellationToken);
|
await database.SaveChangesAsync(executeContext.CancellationToken);
|
||||||
|
|
||||||
return executeContext.Completed();
|
return executeContext.Completed();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
using Musify.Application.Contracts.Infrastructure;
|
using Musify.Application.Contracts.Infrastructure;
|
||||||
using Musify.Application.Events;
|
using Musify.Application.Events;
|
||||||
|
using Musify.Infrastructure.Messaging.Activities;
|
||||||
using Musify.Infrastructure.Messaging.Activities.Arguments;
|
using Musify.Infrastructure.Messaging.Activities.Arguments;
|
||||||
|
|
||||||
namespace Musify.Infrastructure.Messaging.Consumers
|
namespace Musify.Infrastructure.Messaging.Consumers
|
||||||
@@ -26,49 +27,38 @@ namespace Musify.Infrastructure.Messaging.Consumers
|
|||||||
playListConfiguration.Routes.LargePictures,
|
playListConfiguration.Routes.LargePictures,
|
||||||
$"{consumeContext.Message.PlayListId}_large.{pictureHandler.FileExtension}");
|
$"{consumeContext.Message.PlayListId}_large.{pictureHandler.FileExtension}");
|
||||||
|
|
||||||
routingSlipBuilder.AddActivity(
|
AddResizeActivity(
|
||||||
|
routingSlipBuilder,
|
||||||
"ResizeSmall",
|
"ResizeSmall",
|
||||||
new Uri("Queue:Resize-Picture_Execute"),
|
smallPictureKeyName,
|
||||||
new ResizePictureArgument(
|
playListConfiguration.PicturesSizes.SmallPictureWidth,
|
||||||
storageSettings.BucketName,
|
playListConfiguration.PicturesSizes.SmallPictureHeight,
|
||||||
consumeContext.Message.OriginalPictureKeyName,
|
consumeContext.Message.OriginalPictureKeyName);
|
||||||
storageSettings.BucketName,
|
|
||||||
playListConfiguration.Routes.SmallPictures,
|
|
||||||
playListConfiguration.PicturesSizes.SmallPictureWidth,
|
|
||||||
playListConfiguration.PicturesSizes.SmallPictureHeight));
|
|
||||||
|
|
||||||
routingSlipBuilder.AddActivity(
|
|
||||||
"ResizeMedium",
|
|
||||||
new Uri("Queue:Resize-Picture_Execute"),
|
|
||||||
new ResizePictureArgument(
|
|
||||||
storageSettings.BucketName,
|
|
||||||
consumeContext.Message.OriginalPictureKeyName,
|
|
||||||
storageSettings.BucketName,
|
|
||||||
playListConfiguration.Routes.MediumPictures,
|
|
||||||
playListConfiguration.PicturesSizes.MediumPictureWidth,
|
|
||||||
playListConfiguration.PicturesSizes.MediumPictureHeight));
|
|
||||||
|
|
||||||
routingSlipBuilder.AddActivity(
|
AddResizeActivity(
|
||||||
|
routingSlipBuilder,
|
||||||
|
"ResizeMedium",
|
||||||
|
mediumPictureKeyName,
|
||||||
|
playListConfiguration.PicturesSizes.MediumPictureWidth,
|
||||||
|
playListConfiguration.PicturesSizes.MediumPictureHeight,
|
||||||
|
consumeContext.Message.OriginalPictureKeyName);
|
||||||
|
|
||||||
|
AddResizeActivity(
|
||||||
|
routingSlipBuilder,
|
||||||
"ResizeLarge",
|
"ResizeLarge",
|
||||||
new Uri("Queue:Resize-Picture_Execute"),
|
largePictureKeyName,
|
||||||
new ResizePictureArgument(
|
playListConfiguration.PicturesSizes.LargePictureWidth,
|
||||||
storageSettings.BucketName,
|
playListConfiguration.PicturesSizes.LargePictureHeight,
|
||||||
consumeContext.Message.OriginalPictureKeyName,
|
consumeContext.Message.OriginalPictureKeyName);
|
||||||
storageSettings.BucketName,
|
|
||||||
playListConfiguration.Routes.LargePictures,
|
|
||||||
playListConfiguration.PicturesSizes.LargePictureWidth,
|
|
||||||
playListConfiguration.PicturesSizes.LargePictureHeight));
|
|
||||||
|
|
||||||
routingSlipBuilder.AddActivity(
|
routingSlipBuilder.AddActivity(
|
||||||
"DeleteOriginal",
|
"DeleteOriginal",
|
||||||
new Uri("Queue:Delete-Picture_Execute"),
|
BuildExecuteUri(RemoveFilesActivity.ExecuteEndpointName),
|
||||||
new RemoveFileArguments(
|
new RemoveFileArguments(storageSettings.BucketName, consumeContext.Message.OriginalPictureKeyName));
|
||||||
storageSettings.BucketName,
|
|
||||||
consumeContext.Message.OriginalPictureKeyName));
|
|
||||||
|
|
||||||
routingSlipBuilder.AddActivity(
|
routingSlipBuilder.AddActivity(
|
||||||
"UpdatePlayListPicture",
|
"UpdatePlayListPicture",
|
||||||
new Uri("Queue:Update-PlayList-Picture_Execute"),
|
BuildExecuteUri(UpdatePlayListPictureActivity.ExecuteEndpointName),
|
||||||
new UpdatePlayListPictureArguments(
|
new UpdatePlayListPictureArguments(
|
||||||
consumeContext.Message.PlayListId,
|
consumeContext.Message.PlayListId,
|
||||||
smallPictureKeyName,
|
smallPictureKeyName,
|
||||||
@@ -78,5 +68,27 @@ namespace Musify.Infrastructure.Messaging.Consumers
|
|||||||
var routingSlip = routingSlipBuilder.Build();
|
var routingSlip = routingSlipBuilder.Build();
|
||||||
await bus.Execute(routingSlip);
|
await bus.Execute(routingSlip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddResizeActivity(
|
||||||
|
RoutingSlipBuilder routingSlipBuilder,
|
||||||
|
string activityName,
|
||||||
|
string destinationKeyName,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
string originalPictureKeyName)
|
||||||
|
{
|
||||||
|
routingSlipBuilder.AddActivity(
|
||||||
|
activityName,
|
||||||
|
BuildExecuteUri(ResizePictureActivity.ExecuteEndpointName),
|
||||||
|
new ResizePictureArgument(
|
||||||
|
storageSettings.BucketName,
|
||||||
|
originalPictureKeyName,
|
||||||
|
storageSettings.BucketName,
|
||||||
|
destinationKeyName,
|
||||||
|
width,
|
||||||
|
height));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uri BuildExecuteUri(string endpointName) => new($"queue:{endpointName}_execute");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using MassTransit;
|
using MassTransit;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Musify.Infrastructure.Messaging.Activities;
|
||||||
|
using Musify.Infrastructure.Messaging.Activities.Arguments;
|
||||||
using Musify.Infrastructure.Messaging.Consumers;
|
using Musify.Infrastructure.Messaging.Consumers;
|
||||||
|
|
||||||
namespace Musify.Infrastructure.Messaging
|
namespace Musify.Infrastructure.Messaging
|
||||||
@@ -11,26 +13,10 @@ namespace Musify.Infrastructure.Messaging
|
|||||||
{
|
{
|
||||||
serviceDescriptors.AddMassTransit(options =>
|
serviceDescriptors.AddMassTransit(options =>
|
||||||
{
|
{
|
||||||
options.UsingRabbitMq((busRegistrationContext, busFactoryConfigurator) =>
|
options.UsingRabbitMq((_, busFactoryConfigurator) =>
|
||||||
{
|
ConfigureRabbitMqHost(busFactoryConfigurator, configuration));
|
||||||
var section = configuration.GetSection("MassTransit");
|
|
||||||
|
|
||||||
var host = section["Host"]
|
|
||||||
?? throw new InvalidOperationException("MassTransit:Host configuration value not found.");
|
|
||||||
|
|
||||||
var username = section["Username"]
|
|
||||||
?? throw new InvalidOperationException("MassTransit:Username configuration value not found.");
|
|
||||||
|
|
||||||
var password = section["Password"]
|
|
||||||
?? throw new InvalidOperationException("MassTransit:Password configuration value not found.");
|
|
||||||
|
|
||||||
busFactoryConfigurator.Host(host, options =>
|
|
||||||
{
|
|
||||||
options.Username(username);
|
|
||||||
options.Password(password);
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
return serviceDescriptors;
|
return serviceDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,34 +25,70 @@ namespace Musify.Infrastructure.Messaging
|
|||||||
serviceDescriptors.AddMassTransit(options =>
|
serviceDescriptors.AddMassTransit(options =>
|
||||||
{
|
{
|
||||||
options.AddConsumer<UpdatePlayListPictureConsumer>();
|
options.AddConsumer<UpdatePlayListPictureConsumer>();
|
||||||
|
options.AddExecuteActivity<ResizePictureActivity, ResizePictureArgument>();
|
||||||
|
options.AddExecuteActivity<RemoveFilesActivity, RemoveFileArguments>();
|
||||||
|
options.AddExecuteActivity<UpdatePlayListPictureActivity, UpdatePlayListPictureArguments>();
|
||||||
|
|
||||||
options.UsingRabbitMq((busRegistrationContext, busFactoryConfigurator) =>
|
options.UsingRabbitMq((busRegistrationContext, busFactoryConfigurator) =>
|
||||||
{
|
{
|
||||||
var section = configuration.GetSection("MassTransit");
|
ConfigureRabbitMqHost(busFactoryConfigurator, configuration);
|
||||||
|
|
||||||
var host = section["Host"]
|
|
||||||
?? throw new InvalidOperationException("MassTransit:Host configuration value not found.");
|
|
||||||
|
|
||||||
var username = section["Username"]
|
|
||||||
?? throw new InvalidOperationException("MassTransit:Username configuration value not found.");
|
|
||||||
|
|
||||||
var password = section["Password"]
|
|
||||||
?? throw new InvalidOperationException("MassTransit:Password configuration value not found.");
|
|
||||||
|
|
||||||
busFactoryConfigurator.Host(host, options =>
|
|
||||||
{
|
|
||||||
options.Username(username);
|
|
||||||
options.Password(password);
|
|
||||||
} );
|
|
||||||
|
|
||||||
busFactoryConfigurator.ReceiveEndpoint(UpdatePlayListPictureConsumer.QueueName, endpointConfigurator =>
|
busFactoryConfigurator.ReceiveEndpoint(UpdatePlayListPictureConsumer.QueueName, endpointConfigurator =>
|
||||||
{
|
{
|
||||||
endpointConfigurator.ConfigureConsumer<UpdatePlayListPictureConsumer>(busRegistrationContext);
|
endpointConfigurator.ConfigureConsumer<UpdatePlayListPictureConsumer>(busRegistrationContext);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
ConfigureExecuteActivityEndpoint<ResizePictureActivity, ResizePictureArgument>(
|
||||||
|
busFactoryConfigurator,
|
||||||
|
busRegistrationContext,
|
||||||
|
ResizePictureActivity.ExecuteEndpointName);
|
||||||
|
|
||||||
|
ConfigureExecuteActivityEndpoint<RemoveFilesActivity, RemoveFileArguments>(
|
||||||
|
busFactoryConfigurator,
|
||||||
|
busRegistrationContext,
|
||||||
|
RemoveFilesActivity.ExecuteEndpointName);
|
||||||
|
|
||||||
|
ConfigureExecuteActivityEndpoint<UpdatePlayListPictureActivity, UpdatePlayListPictureArguments>(
|
||||||
|
busFactoryConfigurator,
|
||||||
|
busRegistrationContext,
|
||||||
|
UpdatePlayListPictureActivity.ExecuteEndpointName);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
return serviceDescriptors;
|
return serviceDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ConfigureRabbitMqHost(IRabbitMqBusFactoryConfigurator busFactoryConfigurator, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var section = configuration.GetSection("MassTransit");
|
||||||
|
|
||||||
|
var host = section["Host"]
|
||||||
|
?? throw new InvalidOperationException("MassTransit:Host configuration value not found.");
|
||||||
|
|
||||||
|
var username = section["Username"]
|
||||||
|
?? throw new InvalidOperationException("MassTransit:Username configuration value not found.");
|
||||||
|
|
||||||
|
var password = section["Password"]
|
||||||
|
?? throw new InvalidOperationException("MassTransit:Password configuration value not found.");
|
||||||
|
|
||||||
|
busFactoryConfigurator.Host(host, options =>
|
||||||
|
{
|
||||||
|
options.Username(username);
|
||||||
|
options.Password(password);
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConfigureExecuteActivityEndpoint<TActivity, TArguments>(
|
||||||
|
IRabbitMqBusFactoryConfigurator busFactoryConfigurator,
|
||||||
|
IBusRegistrationContext busRegistrationContext,
|
||||||
|
string endpointName)
|
||||||
|
where TActivity : class, IExecuteActivity<TArguments>
|
||||||
|
where TArguments : class
|
||||||
|
{
|
||||||
|
busFactoryConfigurator.ReceiveEndpoint($"{endpointName}_execute", endpointConfigurator =>
|
||||||
|
{
|
||||||
|
endpointConfigurator.ExecuteActivityHost<TActivity, TArguments>(busRegistrationContext);
|
||||||
|
} );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user