using MassTransit; using Microsoft.Extensions.Logging; using Musify.Application.Contracts.Infrastructure; using Musify.Domain.Entities; using Musify.Infrastructure.MassTransit.Activities.Arguments; using Musify.Infrastructure.MassTransit.Activities.Logs; namespace Musify.Infrastructure.MassTransit.Activities { public class UpdateTrackPictureActivity( IDatabase database, ILogger logger) : IActivity { public const string ExecuteEndpointName = "update-track-picture"; public async Task Execute(ExecuteContext executeContext) { var smallResizedVariable = executeContext.GetVariable(executeContext.Arguments.SmallPictureVariable); ArgumentNullException.ThrowIfNull(smallResizedVariable, nameof(smallResizedVariable)); var mediumResizedVariable = executeContext.GetVariable(executeContext.Arguments.MediumPictureVariable); ArgumentNullException.ThrowIfNull(mediumResizedVariable, nameof(mediumResizedVariable)); var largeResizedVariable = executeContext.GetVariable(executeContext.Arguments.LargePictureVariable); ArgumentNullException.ThrowIfNull(largeResizedVariable, nameof(largeResizedVariable)); try { var track = await database.Tracks.FindAsync( [executeContext.Arguments.TrackId], cancellationToken: executeContext.CancellationToken); if (track is null) { logger.LogWarning("Track {TrackId} not found", executeContext.Arguments.TrackId); throw new InvalidOperationException($"Track with id {executeContext.Arguments.TrackId} not found"); } var log = new UpdateTrackPictureLog( track.Id, track.OriginalPictureName, track.SmallPictureName, track.MediumPictureName, track.LargePictureName); track.OriginalPictureName = Path.GetFileName(executeContext.Arguments.OriginalPictureKey); track.SmallPictureName = Path.GetFileName(smallResizedVariable); track.MediumPictureName = Path.GetFileName(mediumResizedVariable); track.LargePictureName = Path.GetFileName(largeResizedVariable); database.Tracks.Update(track); await database.SaveChangesAsync(executeContext.CancellationToken); logger.LogInformation("Updated track {TrackId} pictures", executeContext.Arguments.TrackId); return executeContext.Completed(); } catch (Exception exception) { logger.LogError(exception, "Failed to update track {TrackId} pictures", executeContext.Arguments.TrackId); throw; } } public async Task Compensate(CompensateContext compensateContext) { try { var track = await database.Tracks.FindAsync( [compensateContext.Log.TrackId], cancellationToken: compensateContext.CancellationToken); if (track is null) { return compensateContext.Compensated(); } track.OriginalPictureName = compensateContext.Log.PreviousOriginalPictureKey; track.SmallPictureName = compensateContext.Log.PreviousSmallPictureKey; track.MediumPictureName = compensateContext.Log.PreviousMediumPictureKey; track.LargePictureName = compensateContext.Log.PreviousLargePictureKey; database.Tracks.Update(track); await database.SaveChangesAsync(compensateContext.CancellationToken); return compensateContext.Compensated(); } catch (Exception exception) { logger.LogError(exception, "Failed to compensate track {TrackId} pictures", compensateContext.Log.TrackId); return compensateContext.Failed(exception); } } } }