Renames and changes

This commit is contained in:
2026-03-28 15:32:36 +01:00
parent d2a1807883
commit 06ef70cb3b
28 changed files with 236 additions and 241 deletions
@@ -4,19 +4,19 @@ namespace Musify.Application.Contracts.Infrastructure
{
public interface IStorageHandler
{
Task<Result<Stream>> GetFileAsync(string bucketName, string keyName, CancellationToken cancellationToken);
Task<Result<Stream>> GetFileAsync(string bucket, string key, CancellationToken cancellationToken);
Task<string> GetUrlAsync(string bucketName, string keyName, TimeSpan ExpirationTime, CancellationToken cancellationToken);
Task<string> GetUrlAsync(string bucket, string key, TimeSpan ExpirationTime, CancellationToken cancellationToken);
Task<Result<string>> UploadFileAsync(string filePath, string bucketName, string keyName, CancellationToken cancellationToken);
Task<Result<string>> UploadFileAsync(string filePath, string bucket, string key, CancellationToken cancellationToken);
Task<Result<string>> UploadFileAsync(Stream sourceStream, string contentType, string bucketName, string keyName, CancellationToken cancellationToken);
Task<Result<string>> UploadFileAsync(Stream sourceStream, string contentType, string bucket, string key, CancellationToken cancellationToken);
Task<Result> TransferFilesAsync(string sourceDirectory, string bucketName, string route, CancellationToken cancellationToken);
Task<Result> TransferFilesAsync(string sourceDirectory, string bucket, string route, CancellationToken cancellationToken);
Task<Result> RemoveFileAsync(string bucketName, string keyName, CancellationToken cancellationToken);
Task<Result> RemoveFileAsync(string bucket, string key, CancellationToken cancellationToken);
Task<Result> CopyFileAsync(string sourceBucketName, string sourceKeyName, string destinationBucketName, string destinationKeyName,
Task<Result> CopyFileAsync(string sourceBucket, string sourceKey, string destinationBucket, string destinationKey,
CancellationToken cancellationToken);
}
}
@@ -32,10 +32,10 @@ namespace Musify.Application.PlayLists.Handlers
Name = request.Name,
NormalizedName = request.Name.Trim().ToUpperInvariant(),
Description = request.Description,
OriginalPictureKeyName = playListConfiguration.Routes.PresetOriginalPicture,
SmallPictureKeyName = playListConfiguration.Routes.PresetSmallPicture,
MediumPictureKeyName = playListConfiguration.Routes.PresetMediumPicture,
LargePictureKeyName = playListConfiguration.Routes.PresetLargePicture,
OriginalPictureName = playListConfiguration.Routes.PresetOriginalPicture,
SmallPictureName = playListConfiguration.Routes.PresetSmallPicture,
MediumPictureName = playListConfiguration.Routes.PresetMediumPicture,
LargePictureName = playListConfiguration.Routes.PresetLargePicture,
};
var setPictureResult = request.Picture is null
@@ -63,12 +63,12 @@ namespace Musify.Application.PlayLists.Handlers
if (!uploadResult.IsSuccess)
{
logger.LogError("Failed to upload picture for PlayList with Id={PlayListId} to storage. Storage handler returned error: {ErrorMessage}",
logger.LogError("Failed to upload picture for PlayList with Id={PlayListId} to storage. Storage handler returned error={ErrorMessage}",
playList.Id, string.Join("; ", uploadResult.Errors));
return Result.Error($"Failed to upload picture for PlayList with Id {playList.Id} to storage.");
}
playList.OriginalPictureKeyName = pictureName;
playList.OriginalPictureName = pictureName;
logger.LogInformation("Playlist image uploaded successfully for PlayList with Id={PlayListId}.", playList.Id);
try
@@ -30,15 +30,15 @@ namespace Musify.Application.PlayLists.Handlers
var keysToRemove = new List<string>();
if (playList.SmallPictureKeyName != playListConfiguration.Routes.PresetSmallPicture)
if (playList.SmallPictureName != playListConfiguration.Routes.PresetSmallPicture)
keysToRemove.Add(Path.Combine(playListConfiguration.Routes.SmallPicturesPath,
playList.SmallPictureKeyName));
if (playList.MediumPictureKeyName != playListConfiguration.Routes.PresetMediumPicture)
playList.SmallPictureName));
if (playList.MediumPictureName != playListConfiguration.Routes.PresetMediumPicture)
keysToRemove.Add(Path.Combine(playListConfiguration.Routes.MediumPicturesPath,
playList.MediumPictureKeyName));
if (playList.LargePictureKeyName != playListConfiguration.Routes.PresetLargePicture)
playList.MediumPictureName));
if (playList.LargePictureName != playListConfiguration.Routes.PresetLargePicture)
keysToRemove.Add(Path.Combine(playListConfiguration.Routes.LargePicturesPath,
playList.LargePictureKeyName));
playList.LargePictureName));
foreach (var key in keysToRemove)
{
@@ -48,7 +48,7 @@ namespace Musify.Application.PlayLists.Handlers
{
if (publishResult.IsNotFound())
{
logger.LogWarning("File with key={KeyName} not found in storage while trying to publish remove file event for PlayList with id={PlayListId}.", key, playList.Id);
logger.LogWarning("File with key={Key} not found in storage while trying to publish remove file event for PlayList with id={PlayListId}.", key, playList.Id);
continue;
}
@@ -62,19 +62,19 @@ namespace Musify.Application.PlayLists.Handlers
return Result.NoContent();
}
async Task<Result> TryPublishRemoveFileEventAsync(Guid playListId, string keyName, CancellationToken cancellationToken)
async Task<Result> TryPublishRemoveFileEventAsync(Guid playListId, string key, CancellationToken cancellationToken)
{
try
{
await eventBus.PublishAsync(new RemoveFileEvent(
storageConfiguration.BucketName,
keyName), cancellationToken);
key), cancellationToken);
return Result.Success();
}
catch (Exception exception)
{
logger.LogError(exception, "Failed to publish remove file event for PlayList id={PlayListId} and key={KeyName}.", playListId, keyName);
logger.LogError(exception, "Failed to publish remove file event for PlayList id={PlayListId} and key={Key}.", playListId, key);
return Result.Error($"Failed to publish remove file event for PlayList with id {playListId}.");
}
}
@@ -23,13 +23,13 @@ namespace Musify.Application.PlayLists.Handlers
if (playList is null)
{
logger.LogInformation("PlayList with id {PlayListId} not found", request.PlayListId);
logger.LogInformation("PlayList with id={PlayListId} not found", request.PlayListId);
return Result.NotFound();
}
if (playList.UserId != request.UserId)
{
logger.LogWarning("User with id {UserId} is not the owner of the PlayList with id {PlayListId}", request.UserId, request.PlayListId);
logger.LogWarning("User with id={UserId} is not the owner of the PlayList with id={PlayListId}", request.UserId, request.PlayListId);
return Result.Unauthorized();
}
@@ -51,20 +51,20 @@ namespace Musify.Application.PlayLists.Handlers
return Result.Success(PlayListResponse.FromEntity(playList));
}
if (playList.SmallPictureKeyName != playListConfiguration.Routes.PresetSmallPicture)
if (playList.SmallPictureName != playListConfiguration.Routes.PresetSmallPicture)
await PublishRemoveFileEvent(Path.Combine(
playListConfiguration.Routes.SmallPicturesPath,
playList.SmallPictureKeyName),
playList.SmallPictureName),
cancellationToken);
if (playList.MediumPictureKeyName != playListConfiguration.Routes.PresetMediumPicture)
if (playList.MediumPictureName != playListConfiguration.Routes.PresetMediumPicture)
await PublishRemoveFileEvent(Path.Combine(
playListConfiguration.Routes.MediumPicturesPath,
playList.MediumPictureKeyName),
playList.MediumPictureName),
cancellationToken);
if (playList.LargePictureKeyName != playListConfiguration.Routes.PresetLargePicture)
if (playList.LargePictureName != playListConfiguration.Routes.PresetLargePicture)
await PublishRemoveFileEvent(Path.Combine(
playListConfiguration.Routes.LargePicturesPath,
playList.LargePictureKeyName),
playList.LargePictureName),
cancellationToken);
var newImageId = Guid.NewGuid();
@@ -74,7 +74,7 @@ namespace Musify.Application.PlayLists.Handlers
var uploadResult = await UploadFile(request.NewPicture, newImageStorageKey, cancellationToken);
if (!uploadResult.IsSuccess)
{
logger.LogError("Failed to upload picture for PlayList with Id={PlayListId} to storage. Storage handler returned error: {ErrorMessage}",
logger.LogError("Failed to upload picture for PlayList with Id={PlayListId} to storage. Storage handler returned error?={ErrorMessage}",
playList.Id, string.Join("; ", uploadResult.Errors));
return Result.Error($"Failed to upload picture for PlayList with Id {playList.Id} to storage.");
}
@@ -85,14 +85,14 @@ namespace Musify.Application.PlayLists.Handlers
}
catch (Exception exception)
{
logger.LogError(exception, "Failed to publish update picture event for PlayList with id {PlayListId}.", playList.Id);
logger.LogError(exception, "Failed to publish update picture event for PlayList with id={PlayListId}.", playList.Id);
return Result.Error($"Failed to publish update picture event for PlayList with id {playList.Id}.");
}
database.PlayLists.Update(playList);
await database.SaveChangesAsync(cancellationToken);
logger.LogInformation("Updated PlayList with id={PlayListId} and picture key {PictureKey}.", playList.Id, newImageStorageKey);
logger.LogInformation("Updated PlayList with id={PlayListId} and picture key={PictureKey}.", playList.Id, newImageStorageKey);
return Result.Success(PlayListResponse.FromEntity(playList));
}
@@ -110,7 +110,7 @@ namespace Musify.Application.PlayLists.Handlers
}
catch (Exception exception)
{
logger.LogError(exception, "Failed to publish remove file event for key {Key}.", key);
logger.LogError(exception, "Failed to publish remove file event for key={Key}.", key);
return Result.Error($"Failed to publish remove file event for key {key}.");
}
}
@@ -18,9 +18,9 @@ namespace Musify.Application.PlayLists.Responses
playList.Id,
playList.Name,
playList.Description,
playList.SmallPictureKeyName,
playList.MediumPictureKeyName,
playList.LargePictureKeyName,
playList.SmallPictureName,
playList.MediumPictureName,
playList.LargePictureName,
playList.CreatedDate,
playList.UpdatedDate);
}
@@ -21,7 +21,7 @@ namespace Musify.Application.Tracks.Handler
if (userExists is null)
{
logger.LogWarning("User with id {UserId} not found", request.UserId);
logger.LogWarning("User with id={UserId} not found", request.UserId);
return Result.NotFound($"User with id {request.UserId} not found");
}
@@ -31,11 +31,11 @@ namespace Musify.Application.Tracks.Handler
{
Title = request.Title,
NormalizedTitle = request.Title.Trim().ToUpperInvariant(),
OriginalPictureKeyName = originalPictureFileName,
OriginalAudioKeyName = originalAudioFileName,
SmallPictureKeyName = trackConfiguration.Routes.PresetMediumPicture,
MediumPictureKeyName = trackConfiguration.Routes.PresetMediumPicture,
LargePictureKeyName = trackConfiguration.Routes.PresetLargePicture,
OriginalPictureName = originalPictureFileName,
OriginalAudioName = originalAudioFileName,
SmallPictureName = trackConfiguration.Routes.PresetMediumPicture,
MediumPictureName = trackConfiguration.Routes.PresetMediumPicture,
LargePictureName = trackConfiguration.Routes.PresetLargePicture,
};
var originalPictureKey = Path.Combine(trackConfiguration.Routes.OriginalPicturesPath,
@@ -43,7 +43,7 @@ namespace Musify.Application.Tracks.Handler
var pictureUploadResult = await UploadFile(request.Picture, originalPictureKey, cancellationToken);
if (!pictureUploadResult.IsSuccess)
{
logger.LogError("Failed to upload picture for track {TrackTitle}", request.Title);
logger.LogError("Failed to upload picture for track={TrackTitle}", request.Title);
return Result.Error($"Failed to upload picture for track {request.Title}");
}
@@ -53,7 +53,7 @@ namespace Musify.Application.Tracks.Handler
var audioUploadResult = await UploadFile(request.Audio, audioKey, cancellationToken);
if (!audioUploadResult.IsSuccess)
{
logger.LogError("Failed to upload audio for track {TrackTitle}", request.Title);
logger.LogError("Failed to upload audio for track={TrackTitle}", request.Title);
return Result.Error($"Failed to upload audio for track {request.Title}");
}
@@ -14,8 +14,6 @@ namespace Musify.Application.Users.Handlers
{
public async Task<Result<UserResponse>> Handle(CreateUserCommand request, CancellationToken cancellationToken)
{
logger.LogDebug("Handling {CommandName} with Id: {UserId}", nameof(CreateUserCommand), request.Id);
var existingUser = await database.Users.SingleOrDefaultAsync(u => u.Id == request.Id, cancellationToken);
if (existingUser is not null)
+5 -5
View File
@@ -22,24 +22,24 @@ namespace Musify.Domain.Entities
public required string NormalizedName { get; set; }
[Required]
[MaxLength(254)]
[MaxLength(256)]
public required string Description { get; set; } = "No description was provided.";
[Required]
[MaxLength(64)]
public required string OriginalPictureKeyName { get; set; }
public required string OriginalPictureName { get; set; }
[Required]
[MaxLength(64)]
public required string SmallPictureKeyName { get; set; }
public required string SmallPictureName { get; set; }
[Required]
[MaxLength(64)]
public required string MediumPictureKeyName { get; set; }
public required string MediumPictureName { get; set; }
[Required]
[MaxLength(64)]
public required string LargePictureKeyName { get; set; }
public required string LargePictureName { get; set; }
[Required]
public DateTime CreatedDate { get; set; } = DateTime.UtcNow;
+6 -6
View File
@@ -18,26 +18,26 @@ namespace Musify.Domain.Entities
[Required]
[MaxLength(64)]
public required string OriginalPictureKeyName { get; set; }
public required string OriginalPictureName { get; set; }
[Required]
[MaxLength(64)]
public required string SmallPictureKeyName { get; set; }
public required string SmallPictureName { get; set; }
[Required]
[MaxLength(64)]
public required string MediumPictureKeyName { get; set; }
public required string MediumPictureName { get; set; }
[Required]
[MaxLength(64)]
public required string LargePictureKeyName { get; set; }
public required string LargePictureName { get; set; }
[Required]
[MaxLength(64)]
public required string OriginalAudioKeyName { get; set; }
public required string OriginalAudioName { get; set; }
[MaxLength(64)]
public string AudioFolderKeyName { get; set; } = string.Empty;
public string AudioFolderName { get; set; } = string.Empty;
[Required]
public DateTime CreatedDate { get; set; } = DateTime.UtcNow;
+2 -2
View File
@@ -10,10 +10,10 @@ namespace Musify.Domain.Entities
public Guid Id { get; set; } = Guid.NewGuid();
[Required]
public required string KeyName { get; set; }
public required string Bucket { get; set; }
[Required]
public required string BucketName { get; set; }
public required string Key { get; set; }
[Required]
public required string ContentType { get; set; }
+17 -17
View File
@@ -18,7 +18,7 @@ namespace Musify.Infrastructure.Audio
Directory.CreateDirectory(destinationPath);
logger.LogInformation(
"Starting audio transcoding to DASH. DestinationPath: {DestinationPath}, Timeout: {Timeout}, Executable: {Executable}",
"Starting audio transcoding to DASH. DestinationPath={DestinationPath}, Timeout={Timeout}, Executable={Executable}",
destinationPath,
audioTranscoderConfiguration.TranscodingTimeout,
audioTranscoderConfiguration.Ffmpeg.ExecutableName);
@@ -33,24 +33,24 @@ namespace Musify.Infrastructure.Audio
if (executionResult.ExitCode != 0)
{
logger.LogError(
"Audio transcoding to DASH format failed with exit code {ExitCode}. Standard Output: {StandardOutput}, Standard Error: {StandardError}",
"Audio transcoding to DASH format failed with exit code={ExitCode}. Standard Output={StandardOutput}, Standard Error={StandardError}",
executionResult.ExitCode,
executionResult.StandardOutput,
executionResult.StandardError);
return Result.Error($"Audio transcoding failed with exit code {executionResult.ExitCode}. See logs for details.");
return Result.Error($"Audio transcoding failed with exit code: {executionResult.ExitCode}. See logs for details.");
}
logger.LogInformation("Audio transcoding to DASH format completed successfully. DestinationPath: {DestinationPath}", destinationPath);
logger.LogInformation("Audio transcoding to DASH format completed successfully. DestinationPath={DestinationPath}", destinationPath);
return Result.Success();
}
catch (TimeoutException timeoutException)
{
logger.LogError(timeoutException, "Audio transcoding timed out after {Timeout}. DestinationPath: {DestinationPath}", audioTranscoderConfiguration.TranscodingTimeout, destinationPath);
logger.LogError(timeoutException, "Audio transcoding timed out after={Timeout}. DestinationPath={DestinationPath}", audioTranscoderConfiguration.TranscodingTimeout, destinationPath);
return Result.Error("Audio transcoding timed out.");
}
catch (Exception exception)
{
logger.LogError(exception, "An error occurred while transcoding audio to DASH format. DestinationPath: {DestinationPath}", destinationPath);
logger.LogError(exception, "An error occurred while transcoding audio to DASH format. DestinationPath={DestinationPath}", destinationPath);
return Result.Error(exception.Message);
}
}
@@ -59,13 +59,13 @@ namespace Musify.Infrastructure.Audio
{
if (!File.Exists(filePath))
{
logger.LogWarning("Audio validation requested for a non-existing file. FilePath: {FilePath}", filePath);
logger.LogWarning("Audio validation requested for a non-existing file. FilePath={FilePath}", filePath);
return Result<bool>.Error($"Audio file not found: {filePath}");
}
try
{
logger.LogInformation("Starting audio file validation. FilePath: {FilePath}, Timeout: {Timeout}", filePath, audioTranscoderConfiguration.TranscodingTimeout);
logger.LogInformation("Starting audio file validation. FilePath={FilePath}, Timeout={Timeout}", filePath, audioTranscoderConfiguration.TranscodingTimeout);
var executionResult = await ExecuteFfmpegAsync(
BuildValidateAudioArguments(filePath),
@@ -77,25 +77,25 @@ namespace Musify.Infrastructure.Audio
if (!isValid)
{
logger.LogWarning(
"Audio validation failed for file {FilePath}. Standard Error: {StandardError}",
"Audio validation failed for file={FilePath}. Standard Error={StandardError}",
filePath,
executionResult.StandardError);
}
else
{
logger.LogInformation("Audio validation completed successfully. FilePath: {FilePath}", filePath);
logger.LogInformation("Audio validation completed successfully. FilePath={FilePath}", filePath);
}
return Result<bool>.Success(isValid);
}
catch (TimeoutException timeoutException)
{
logger.LogError(timeoutException, "Audio validation timed out after {Timeout} for file {FilePath}.", audioTranscoderConfiguration.TranscodingTimeout, filePath);
logger.LogError(timeoutException, "Audio validation timed out after={Timeout} for file={FilePath}.", audioTranscoderConfiguration.TranscodingTimeout, filePath);
return Result<bool>.Error("Audio validation timed out.");
}
catch (Exception exception)
{
logger.LogError(exception, "An error occurred while validating audio file {FilePath}.", filePath);
logger.LogError(exception, "An error occurred while validating audio file={FilePath}.", filePath);
return Result<bool>.Error(exception.Message);
}
}
@@ -110,7 +110,7 @@ namespace Musify.Infrastructure.Audio
using var process = BuildProcess(arguments, workingDirectory, redirectStandardInput: true);
process.Start();
logger.LogDebug("[{Operation}] ffmpeg process started. ProcessId: {ProcessId}, WorkingDirectory: {WorkingDirectory}", operationName, process.Id, workingDirectory);
logger.LogDebug("[{Operation}] ffmpeg process started. ProcessId={ProcessId}, WorkingDirectory={WorkingDirectory}", operationName, process.Id, workingDirectory);
if (inputStream.CanSeek)
inputStream.Position = 0;
@@ -130,7 +130,7 @@ namespace Musify.Infrastructure.Audio
using var process = BuildProcess(arguments, workingDirectory, redirectStandardInput: false);
process.Start();
logger.LogDebug("[{Operation}] ffmpeg process started. ProcessId: {ProcessId}, WorkingDirectory: {WorkingDirectory}", operationName, process.Id, workingDirectory);
logger.LogDebug("[{Operation}] ffmpeg process started. ProcessId={ProcessId}, WorkingDirectory={WorkingDirectory}", operationName, process.Id, workingDirectory);
return await WaitForProcessResultAsync(process, operationName, cancellationToken);
}
@@ -169,7 +169,7 @@ namespace Musify.Infrastructure.Audio
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
logger.LogError(
"[{Operation}] ffmpeg timed out after {Timeout}. ProcessId: {ProcessId}",
"[{Operation}] ffmpeg timed out after={Timeout}. ProcessId={ProcessId}",
operationName,
audioTranscoderConfiguration.TranscodingTimeout,
process.Id);
@@ -182,7 +182,7 @@ namespace Musify.Infrastructure.Audio
var standardOutput = await outputTask;
logger.LogDebug(
"[{Operation}] ffmpeg finished. ProcessId: {ProcessId}, ExitCode: {ExitCode}, StdOutLength: {StdOutLength}, StdErrLength: {StdErrLength}",
"[{Operation}] ffmpeg finished. ProcessId={ProcessId}, ExitCode={ExitCode}, StdOutLength={StdOutLength}, StdErrLength={StdErrLength}",
operationName,
process.Id,
process.ExitCode,
@@ -201,7 +201,7 @@ namespace Musify.Infrastructure.Audio
}
catch (Exception exception)
{
logger.LogError(exception, "Failed to kill ffmpeg process. ProcessId: {ProcessId}", process.Id);
logger.LogError(exception, "Failed to kill ffmpeg process. ProcessId={ProcessId}", process.Id);
}
}
@@ -23,12 +23,12 @@ namespace Musify.Infrastructure.Identity
}
catch (OperationCanceledException)
{
logger.LogError("Operation to retrieve Keycloak user with id {KeycloakId} was cancelled.", keycloakId);
logger.LogError("Operation to retrieve Keycloak user with id={KeycloakId} was cancelled.", keycloakId);
return Result.Error("Operation was cancelled.");
}
catch (Exception exception)
{
logger.LogWarning(exception, "Keycloak user with id {KeycloakId} could not be retrieved.", keycloakId);
logger.LogWarning(exception, "Keycloak user with id={KeycloakId} could not be retrieved.", keycloakId);
return Result.NotFound();
}
return Result.Success(KeycloakUserMapper.Map(keycloakUser));
@@ -38,7 +38,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
Directory.CreateDirectory(workingDirectory);
logger.LogDebug("Generated audio workflow paths. WorkingDirectory: {WorkingDirectory}, SourceFilePath: {SourceFilePath}",
logger.LogDebug("Generated audio workflow paths. WorkingDirectory={WorkingDirectory}, SourceFilePath={SourceFilePath}",
workingDirectory,
sourceFilePath);
@@ -53,7 +53,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error generating audio workflow paths for key {SourceKeyName}",
logger.LogError(exception, "Error generating audio workflow paths for key={SourceKey}",
executeContext.Arguments.SourceKey);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
throw;
@@ -48,7 +48,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
if (!result.IsSuccess)
{
var errorMessage = string.Join("; ", result.Errors);
logger.LogError("Transcoding failed for file {SourceFilePath}. Errors: {ErrorMessage}",
logger.LogError("Transcoding failed for file={SourceFilePath}. Errors={ErrorMessage}",
sourceFilePath, errorMessage);
throw new Exception(errorMessage);
}
@@ -60,7 +60,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error during transcoding activity for file {SourceFilePath}",
logger.LogError(exception, "Error during transcoding activity for file={SourceFilePath}",
sourceFilePath);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
throw;
@@ -74,13 +74,13 @@ namespace Musify.Infrastructure.MassTransit.Activities
if (Directory.Exists(compensateContext.Log.WorkingDirectory))
Directory.Delete(compensateContext.Log.WorkingDirectory, recursive: true);
else
logger.LogWarning("Working directory {WorkingDirectory} does not exist during compensation",
logger.LogWarning("Working directory={WorkingDirectory} does not exist during compensation",
compensateContext.Log.WorkingDirectory);
return Task.FromResult(compensateContext.Compensated());
}
catch (Exception exception)
{
logger.LogError(exception, "Error compensating transcoded audio directory {WorkingDirectory}", compensateContext.Log.WorkingDirectory);
logger.LogError(exception, "Error compensating transcoded audio directory={WorkingDirectory}", compensateContext.Log.WorkingDirectory);
return Task.FromResult(compensateContext.Failed(exception));
}
}
@@ -39,21 +39,21 @@ namespace Musify.Infrastructure.MassTransit.Activities.Audio
if (track is null)
{
logger.LogWarning("Track with id {TrackId} not found",
logger.LogWarning("Track with id={TrackId} not found",
executeContext.Arguments.TrackId);
throw new InvalidOperationException($"Track with id {executeContext.Arguments.TrackId} not found");
}
var log = new UpdateTrackAudioLog(
track.Id,
track.AudioFolderKeyName);
track.AudioFolderName);
track.AudioFolderKeyName = Path.GetFileName(executeContext.Arguments.AudioFolderKey);
track.AudioFolderName = Path.GetFileName(executeContext.Arguments.AudioFolderKey);
database.Tracks.Update(track);
await database.SaveChangesAsync(executeContext.CancellationToken);
logger.LogInformation("Updated Track {TrackId} audio",
logger.LogInformation("Updated Track={TrackId} audio",
executeContext.Arguments.TrackId);
await processTrackingStore.CompleteStepAsync(processId, stepId, executeContext.CancellationToken);
@@ -61,7 +61,7 @@ namespace Musify.Infrastructure.MassTransit.Activities.Audio
}
catch (Exception exception)
{
logger.LogError(exception, "Error updating Track {TrackId} audio",
logger.LogError(exception, "Error updating Track={TrackId} audio",
executeContext.Arguments.TrackId);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
throw;
@@ -81,7 +81,7 @@ namespace Musify.Infrastructure.MassTransit.Activities.Audio
return compensateContext.Compensated();
}
track.AudioFolderKeyName = compensateContext.Log.PreviousFolderAudioKey;
track.AudioFolderName = compensateContext.Log.PreviousFolderAudioKey;
database.Tracks.Update(track);
await database.SaveChangesAsync(compensateContext.CancellationToken);
@@ -90,7 +90,7 @@ namespace Musify.Infrastructure.MassTransit.Activities.Audio
}
catch (Exception exception)
{
logger.LogError(exception, "Error compensating Track {TrackId} audio", compensateContext.Log.TrackId);
logger.LogError(exception, "Error compensating Track={TrackId} audio", compensateContext.Log.TrackId);
return compensateContext.Failed(exception);
}
}
@@ -44,7 +44,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
if (!getFile.IsSuccess)
{
var errorMessage = string.Join("; ", getFile.Errors);
logger.LogWarning("Failed to download file from bucket. Bucket: {BucketName}, Key: {KeyName}, Errors: {Errors}",
logger.LogWarning("Failed to download file from bucket. Bucket={Bucket}, Key={Key}, Errors={Errors}",
executeContext.Arguments.Bucket,
executeContext.Arguments.Key,
errorMessage);
@@ -85,7 +85,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error compensating downloaded file {DestinationFilePath}", compensateContext.Log.DestinationFilePath);
logger.LogError(exception, "Error compensating downloaded file={DestinationFilePath}", compensateContext.Log.DestinationFilePath);
return Task.FromResult(compensateContext.Failed(exception));
}
}
@@ -40,7 +40,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
if (!removeFile.IsSuccess)
{
var errorMessage = string.Join("; ", removeFile.Errors);
logger.LogWarning("Failed to remove file {KeyName} from bucket {BucketName}. Errors: {Errors}",
logger.LogWarning("Failed to remove file={Key} from bucket={Bucket}. Errors={Errors}",
executeContext.Arguments.Key,
executeContext.Arguments.Bucket,
errorMessage);
@@ -51,7 +51,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error removing file {KeyName} from bucket {BucketName}",
logger.LogError(exception, "Error removing file={Key} from bucket={Bucket}",
executeContext.Arguments.Key,
executeContext.Arguments.Bucket);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
@@ -51,7 +51,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
if (!transferFilesResult.IsSuccess)
{
var errorMessage = string.Join("; ", transferFilesResult.Errors);
logger.LogWarning("Failed to transfer files from {FolderPath} to bucket {DestinationBucketName}, key {DestinationKeyName}. Errors: {Errors}",
logger.LogWarning("Failed to transfer files from={FolderPath} to bucket={DestinationBucket}, key={DestinationKey}. Errors={Errors}",
folderPath,
executeContext.Arguments.DestinationBucket,
destinationKey,
@@ -64,7 +64,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error transferring files from {FolderPath} to bucket {DestinationBucketName}",
logger.LogError(exception, "Error transferring files from={FolderPath} to bucket={DestinationBucket}",
folderPath,
executeContext.Arguments.DestinationBucket);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
@@ -88,7 +88,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error compensating transferred files to bucket {DestinationBucketName}", compensateContext.Log.DestinationBucket);
logger.LogError(exception, "Error compensating transferred files to bucket={DestinationBucket}", compensateContext.Log.DestinationBucket);
return compensateContext.Failed(exception);
}
}
@@ -46,7 +46,7 @@ namespace Musify.Infrastructure.MassTransit.Activities.Files
if (!uploadResult.IsSuccess)
{
var errors = string.Join("; ", uploadResult.Errors);
logger.LogWarning("Failed to upload file to bucket. Bucket: {BucketName}, Key: {KeyName}, Errors: {Errors}",
logger.LogWarning("Failed to upload file to bucket. Bucket={Bucket}, Key={Key}, Errors={Errors}",
executeContext.Arguments.DestinationBucket,
executeContext.Arguments.DestinationRoute,
errors);
@@ -60,7 +60,7 @@ namespace Musify.Infrastructure.MassTransit.Activities.Files
}
catch (Exception exception)
{
logger.LogError(exception, "An error occurred while uploading file to bucket for process {ProcessId} at step {StepId}", processId, stepId);
logger.LogError(exception, "An error occurred while uploading file to bucket for process={ProcessId} at step={StepId}", processId, stepId);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
throw;
}
@@ -78,16 +78,15 @@ namespace Musify.Infrastructure.MassTransit.Activities.Files
if (!uploadResult.IsSuccess)
{
var errors = string.Join("; ", uploadResult.Errors);
var errorMessage = $"Failed to remove file from bucket during compensation. Bucket: {compensateContext.Log.DestinationBucket}, Key: {compensateContext.Log.DestinationKey}, Errors: {errors}";
logger.LogError($"Failed to remove file from bucket during compensation. Bucket={compensateContext.Log.DestinationBucket}, Key={compensateContext.Log.DestinationKey}, Errors={errors}");
logger.LogError(errorMessage);
return compensateContext.Failed(new Exception(errorMessage));
return compensateContext.Failed(new Exception($"Failed to remove file from bucket during compensation. Bucket: {compensateContext.Log.DestinationBucket}, Key: {compensateContext.Log.DestinationKey}, Errors: {errors}"));
}
return compensateContext.Compensated();
}
catch (Exception exception)
{
logger.LogError(exception, "An error occurred while compensating upload file to bucket activity for bucket {BucketName} and key {KeyName}",
logger.LogError(exception, "An error occurred while compensating upload file to bucket activity for bucket={Bucket} and key={Key}",
compensateContext.Log.DestinationBucket,
compensateContext.Log.DestinationKey);
return compensateContext.Failed(exception);
@@ -47,7 +47,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
Directory.CreateDirectory(workingDirectory);
logger.LogDebug("Generated picture workflow paths. WorkingDirectory: {WorkingDirectory}, SourceFilePath: {SourceFilePath}",
logger.LogDebug("Generated picture workflow paths. WorkingDirectory={WorkingDirectory}, SourceFilePath={SourceFilePath}",
workingDirectory,
sourceFilePath);
@@ -64,7 +64,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error generating picture workflow paths for key {SourceKeyName}",
logger.LogError(exception, "Error generating picture workflow paths for key={SourceKey}",
executeContext.Arguments.SourceKey);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
throw;
@@ -41,7 +41,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
{
if (!File.Exists(sourceFilePath))
{
logger.LogWarning("Source file not found at {SourceFilePath}", sourceFilePath);
logger.LogWarning("Source file not found at={SourceFilePath}", sourceFilePath);
throw new FileNotFoundException($"Source file not found: {sourceFilePath}");
}
@@ -56,7 +56,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
if (!resizedPicture.IsSuccess)
{
var errorMessage = string.Join("; ", resizedPicture.Errors);
logger.LogError("Failed to resize picture {SourceFilePath} to {Width}x{Height}. Errors: {Errors}",
logger.LogError("Failed to resize picture={SourceFilePath} to={Width}x{Height}. Errors={Errors}",
sourceFilePath,
executeContext.Arguments.Width,
executeContext.Arguments.Height,
@@ -71,18 +71,16 @@ namespace Musify.Infrastructure.MassTransit.Activities
await using var destinationStream = File.Create(destinationFilePath);
await resizedPicture.Value.CopyToAsync(destinationStream, executeContext.CancellationToken);
logger.LogDebug("Picture resized from {SourceFilePath} to {DestinationFilePath} ({Width}x{Height})",
logger.LogDebug("Picture resized from={SourceFilePath} to={DestinationFilePath}",
sourceFilePath,
destinationFilePath,
executeContext.Arguments.Width,
executeContext.Arguments.Height);
destinationFilePath);
await processTrackingStore.CompleteStepAsync(processId, stepId, executeContext.CancellationToken);
return executeContext.Completed(new ResizePictureLog(destinationFilePath));
}
catch (Exception exception)
{
logger.LogError(exception, "Error resizing picture {SourceFilePath}", sourceFilePath);
logger.LogError(exception, "Error resizing picture={SourceFilePath}", sourceFilePath);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
throw;
}
@@ -97,7 +95,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error compensating resized file {DestinationFilePath}", compensateContext.Log.DestinationFilePath);
logger.LogError(exception, "Error compensating resized file={DestinationFilePath}", compensateContext.Log.DestinationFilePath);
return Task.FromResult(compensateContext.Failed(exception));
}
}
@@ -46,27 +46,27 @@ namespace Musify.Infrastructure.MassTransit.Activities
if (playList is null)
{
logger.LogWarning("PlayList with id {PlayListId} not found",
logger.LogWarning("PlayList with id={PlayListId} not found",
executeContext.Arguments.PlayListId);
throw new InvalidOperationException($"PlayList with id {executeContext.Arguments.PlayListId} not found");
}
var log = new UpdatePlayListPictureLog(
playList.Id,
playList.OriginalPictureKeyName,
playList.SmallPictureKeyName,
playList.MediumPictureKeyName,
playList.LargePictureKeyName);
playList.OriginalPictureName,
playList.SmallPictureName,
playList.MediumPictureName,
playList.LargePictureName);
playList.OriginalPictureKeyName = Path.GetFileName(executeContext.Arguments.OriginalPictureKey);
playList.SmallPictureKeyName = Path.GetFileName(smallResizedVariable);
playList.MediumPictureKeyName = Path.GetFileName(mediumResizedVariable);
playList.LargePictureKeyName = Path.GetFileName(largeResizedVariable);
playList.OriginalPictureName = Path.GetFileName(executeContext.Arguments.OriginalPictureKey);
playList.SmallPictureName = Path.GetFileName(smallResizedVariable);
playList.MediumPictureName = Path.GetFileName(mediumResizedVariable);
playList.LargePictureName = Path.GetFileName(largeResizedVariable);
database.PlayLists.Update(playList);
await database.SaveChangesAsync(executeContext.CancellationToken);
logger.LogInformation("Updated PlayList {PlayListId} pictures",
logger.LogInformation("Updated PlayList={PlayListId} pictures",
executeContext.Arguments.PlayListId);
await processTrackingStore.CompleteStepAsync(processId, stepId, executeContext.CancellationToken);
@@ -74,7 +74,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error updating PlayList {PlayListId} pictures",
logger.LogError(exception, "Error updating PlayList={PlayListId} pictures",
executeContext.Arguments.PlayListId);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
throw;
@@ -94,10 +94,10 @@ namespace Musify.Infrastructure.MassTransit.Activities
return compensateContext.Compensated();
}
playList.OriginalPictureKeyName = compensateContext.Log.PreviousOriginalPictureKey;
playList.SmallPictureKeyName = compensateContext.Log.PreviousSmallPictureKey;
playList.MediumPictureKeyName = compensateContext.Log.PreviousMediumPictureKey;
playList.LargePictureKeyName = compensateContext.Log.PreviousLargePictureKey;
playList.OriginalPictureName = compensateContext.Log.PreviousOriginalPictureKey;
playList.SmallPictureName = compensateContext.Log.PreviousSmallPictureKey;
playList.MediumPictureName = compensateContext.Log.PreviousMediumPictureKey;
playList.LargePictureName = compensateContext.Log.PreviousLargePictureKey;
database.PlayLists.Update(playList);
await database.SaveChangesAsync(compensateContext.CancellationToken);
@@ -106,7 +106,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error compensating PlayList {PlayListId} pictures", compensateContext.Log.PlayListId);
logger.LogError(exception, "Error compensating PlayList={PlayListId} pictures", compensateContext.Log.PlayListId);
return compensateContext.Failed(exception);
}
}
@@ -46,27 +46,27 @@ namespace Musify.Infrastructure.MassTransit.Activities
if (track is null)
{
logger.LogWarning("Track with id {TrackId} not found",
logger.LogWarning("Track with id={TrackId} not found",
executeContext.Arguments.TrackId);
throw new InvalidOperationException($"Track with id {executeContext.Arguments.TrackId} not found");
}
var log = new UpdateTrackPictureLog(
track.Id,
track.OriginalPictureKeyName,
track.SmallPictureKeyName,
track.MediumPictureKeyName,
track.LargePictureKeyName);
track.OriginalPictureName,
track.SmallPictureName,
track.MediumPictureName,
track.LargePictureName);
track.OriginalPictureKeyName = Path.GetFileName(executeContext.Arguments.OriginalPictureKey);
track.SmallPictureKeyName = Path.GetFileName(smallResizedVariable);
track.MediumPictureKeyName = Path.GetFileName(mediumResizedVariable);
track.LargePictureKeyName = Path.GetFileName(largeResizedVariable);
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",
logger.LogInformation("Updated Track={TrackId} pictures",
executeContext.Arguments.TrackId);
await processTrackingStore.CompleteStepAsync(processId, stepId, executeContext.CancellationToken);
@@ -74,7 +74,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error updating Track {TrackId} pictures",
logger.LogError(exception, "Error updating Track={TrackId} pictures",
executeContext.Arguments.TrackId);
await processTrackingStore.FailStepAsync(processId, stepId, exception.Message, executeContext.CancellationToken);
throw;
@@ -94,10 +94,10 @@ namespace Musify.Infrastructure.MassTransit.Activities
return compensateContext.Compensated();
}
track.OriginalPictureKeyName = compensateContext.Log.PreviousOriginalPictureKey;
track.SmallPictureKeyName = compensateContext.Log.PreviousSmallPictureKey;
track.MediumPictureKeyName = compensateContext.Log.PreviousMediumPictureKey;
track.LargePictureKeyName = compensateContext.Log.PreviousLargePictureKey;
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);
@@ -106,7 +106,7 @@ namespace Musify.Infrastructure.MassTransit.Activities
}
catch (Exception exception)
{
logger.LogError(exception, "Error compensating Track {TrackId} pictures", compensateContext.Log.TrackId);
logger.LogError(exception, "Error compensating Track={TrackId} pictures", compensateContext.Log.TrackId);
return compensateContext.Failed(exception);
}
}
@@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Musify.Infrastructure.Persistence.Migrations
{
[DbContext(typeof(Database))]
[Migration("20260325003221_FirstMigration")]
[Migration("20260328141805_FirstMigration")]
partial class FirstMigration
{
/// <inheritdoc />
@@ -36,15 +36,15 @@ namespace Musify.Infrastructure.Persistence.Migrations
b.Property<string>("Description")
.IsRequired()
.HasMaxLength(254)
.HasColumnType("character varying(254)");
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("LargePictureKeyName")
b.Property<string>("LargePictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("MediumPictureKeyName")
b.Property<string>("MediumPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -59,12 +59,12 @@ namespace Musify.Infrastructure.Persistence.Migrations
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("OriginalPictureKeyName")
b.Property<string>("OriginalPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("SmallPictureKeyName")
b.Property<string>("SmallPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -195,7 +195,7 @@ namespace Musify.Infrastructure.Persistence.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("AudioFolderKeyName")
b.Property<string>("AudioFolderName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -203,12 +203,12 @@ namespace Musify.Infrastructure.Persistence.Migrations
b.Property<DateTime>("CreatedDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("LargePictureKeyName")
b.Property<string>("LargePictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("MediumPictureKeyName")
b.Property<string>("MediumPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -218,17 +218,17 @@ namespace Musify.Infrastructure.Persistence.Migrations
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("OriginalAudioKeyName")
b.Property<string>("OriginalAudioName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("OriginalPictureKeyName")
b.Property<string>("OriginalPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("SmallPictureKeyName")
b.Property<string>("SmallPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -252,7 +252,7 @@ namespace Musify.Infrastructure.Persistence.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("BucketName")
b.Property<string>("Bucket")
.IsRequired()
.HasColumnType("text");
@@ -263,7 +263,7 @@ namespace Musify.Infrastructure.Persistence.Migrations
b.Property<DateTime>("CreatedTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("KeyName")
b.Property<string>("Key")
.IsRequired()
.HasColumnType("text");
@@ -37,12 +37,12 @@ namespace Musify.Infrastructure.Persistence.Migrations
Id = table.Column<Guid>(type: "uuid", nullable: false),
Title = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
NormalizedTitle = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
OriginalPictureKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
SmallPictureKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
MediumPictureKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
LargePictureKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
OriginalAudioKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
AudioFolderKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
OriginalPictureName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
SmallPictureName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
MediumPictureName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
LargePictureName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
OriginalAudioName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
AudioFolderName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
CreatedDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
@@ -56,8 +56,8 @@ namespace Musify.Infrastructure.Persistence.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
KeyName = table.Column<string>(type: "text", nullable: false),
BucketName = table.Column<string>(type: "text", nullable: false),
Bucket = table.Column<string>(type: "text", nullable: false),
Key = table.Column<string>(type: "text", nullable: false),
ContentType = table.Column<string>(type: "text", nullable: false),
CreatedTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
State = table.Column<int>(type: "integer", nullable: false)
@@ -113,11 +113,11 @@ namespace Musify.Infrastructure.Persistence.Migrations
UserId = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
NormalizedName = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Description = table.Column<string>(type: "character varying(254)", maxLength: 254, nullable: false),
OriginalPictureKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
SmallPictureKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
MediumPictureKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
LargePictureKeyName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
Description = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
OriginalPictureName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
SmallPictureName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
MediumPictureName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
LargePictureName = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
CreatedDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
@@ -33,15 +33,15 @@ namespace Musify.Infrastructure.Persistence.Migrations
b.Property<string>("Description")
.IsRequired()
.HasMaxLength(254)
.HasColumnType("character varying(254)");
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("LargePictureKeyName")
b.Property<string>("LargePictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("MediumPictureKeyName")
b.Property<string>("MediumPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -56,12 +56,12 @@ namespace Musify.Infrastructure.Persistence.Migrations
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("OriginalPictureKeyName")
b.Property<string>("OriginalPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("SmallPictureKeyName")
b.Property<string>("SmallPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -192,7 +192,7 @@ namespace Musify.Infrastructure.Persistence.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("AudioFolderKeyName")
b.Property<string>("AudioFolderName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -200,12 +200,12 @@ namespace Musify.Infrastructure.Persistence.Migrations
b.Property<DateTime>("CreatedDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("LargePictureKeyName")
b.Property<string>("LargePictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("MediumPictureKeyName")
b.Property<string>("MediumPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -215,17 +215,17 @@ namespace Musify.Infrastructure.Persistence.Migrations
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("OriginalAudioKeyName")
b.Property<string>("OriginalAudioName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("OriginalPictureKeyName")
b.Property<string>("OriginalPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("SmallPictureKeyName")
b.Property<string>("SmallPictureName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
@@ -249,7 +249,7 @@ namespace Musify.Infrastructure.Persistence.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("BucketName")
b.Property<string>("Bucket")
.IsRequired()
.HasColumnType("text");
@@ -260,7 +260,7 @@ namespace Musify.Infrastructure.Persistence.Migrations
b.Property<DateTime>("CreatedTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("KeyName")
b.Property<string>("Key")
.IsRequired()
.HasColumnType("text");
+3 -3
View File
@@ -13,7 +13,7 @@ namespace Musify.Infrastructure.Pictures
{
try
{
logger.LogDebug("Resizing picture to {Width}x{Height}", width, height);
logger.LogDebug("Resizing picture to={Width}x{Height}", width, height);
if (pictureStream.CanSeek && pictureStream.Position > 0)
pictureStream.Position = 0;
@@ -31,12 +31,12 @@ namespace Musify.Infrastructure.Pictures
memoryStream.Position = 0;
logger.LogDebug("Picture resized successfully. OutputLength: {Length}", memoryStream.Length);
logger.LogDebug("Picture resized successfully. OutputLength={Length}", memoryStream.Length);
return Result<Stream>.Success(memoryStream);
}
catch (Exception exception)
{
logger.LogError(exception, "An error occurred while resizing the picture to {Width}x{Height}.", width, height);
logger.LogError(exception, "An error occurred while resizing the picture to={Width}x{Height}.", width, height);
return Result.Error("An error occurred while resizing the picture.");
}
}
+48 -48
View File
@@ -13,61 +13,61 @@ namespace Musify.Infrastructure.Storage
public class StorageHandler(IDatabase database, IAmazonS3 amazonS3, InfrastructureStorageConfiguration storageClientConfiguration, ILogger<StorageHandler> logger)
: IStorageHandler
{
public async Task<Result<Stream>> GetFileAsync(string bucketName, string keyName, CancellationToken cancellationToken)
public async Task<Result<Stream>> GetFileAsync(string bucket, string key, CancellationToken cancellationToken)
{
var request = new GetObjectRequest
{
BucketName = bucketName,
Key = keyName,
BucketName = bucket,
Key = key,
};
logger.LogDebug("Getting file from S3. Bucket: {BucketName}, Key: {KeyName}", bucketName, keyName);
logger.LogDebug("Getting file from S3. Bucket={Bucket}, Key={Key}", bucket, key);
try
{
var response = await amazonS3.GetObjectAsync(request, cancellationToken);
logger.LogDebug("Successfully got file from S3 with bucket name {BucketName} and key name {KeyName}", bucketName, keyName);
logger.LogDebug("Successfully got file from S3 with bucket={Bucket} and key={Key}", bucket, key);
return Result.Success(response.ResponseStream);
}
catch (Exception exception)
{
logger.LogWarning(exception, "Failed to get file from S3. Bucket: {BucketName}, Key: {KeyName}", bucketName, keyName);
return Result.NotFound($"File not found in S3 with bucket name {bucketName} and key name {keyName}");
logger.LogWarning(exception, "Failed to get file from S3. Bucket={Bucket}, Key={Key}", bucket, key);
return Result.NotFound($"File not found in S3 with bucket: {bucket} and key: {key}");
}
}
public async Task<string> GetUrlAsync(string bucketName, string keyName, TimeSpan expirationTime, CancellationToken cancellationToken)
public async Task<string> GetUrlAsync(string bucket, string key, TimeSpan expirationTime, CancellationToken cancellationToken)
{
var request = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Key = keyName,
BucketName = bucket,
Key = key,
Expires = DateTime.UtcNow + expirationTime,
Protocol = storageClientConfiguration.UseHttp ? Protocol.HTTP : Protocol.HTTPS
};
logger.LogDebug("Getting pre-signed URL from S3. Bucket: {BucketName}, Key: {KeyName}, Expires: {Expires}", bucketName, keyName, request.Expires);
logger.LogDebug("Getting pre-signed URL from S3. Bucket={BucketName}, Key={Key}, Expires={Expires}", bucket, key, request.Expires);
var url = await amazonS3.GetPreSignedURLAsync(request);
return url;
}
public async Task<Result> RemoveFileAsync(string bucketName, string keyName, CancellationToken cancellationToken)
public async Task<Result> RemoveFileAsync(string bucket, string key, CancellationToken cancellationToken)
{
var request = new DeleteObjectRequest
{
BucketName = bucketName,
Key = keyName,
BucketName = bucket,
Key = key,
};
logger.LogDebug("Removing file from S3. Bucket: {BucketName}, Key: {KeyName}", bucketName, keyName);
logger.LogDebug("Removing file from S3. Bucket={Bucket}, Key={Key}", bucket, key);
var response = await amazonS3.DeleteObjectAsync(request, cancellationToken);
return Result.NoContent();
}
public async Task<Result> TransferFilesAsync(string sourceDirectory, string bucketName, string route, CancellationToken cancellationToken)
public async Task<Result> TransferFilesAsync(string sourceDirectory, string bucket, string route, CancellationToken cancellationToken)
{
var trasnsferUtility = new TransferUtility(amazonS3);
@@ -81,67 +81,67 @@ namespace Musify.Infrastructure.Storage
string fileName = Path.GetFileName(file);
string filePath = Path.Combine(sourceDirectory, file);
var keyName = Path.Combine(route, fileName);
var key = Path.Combine(route, fileName);
var upload = new Upload
{
Id = Guid.NewGuid(),
BucketName = bucketName,
KeyName = keyName,
ContentType = "Application/Octet-Stream"
Bucket = bucket,
Key = key,
ContentType = MimeUtility.GetMimeMapping(filePath)
};
await database.Uploads.AddAsync(upload, cancellationToken);
try
{
await trasnsferUtility.UploadAsync(filePath, bucketName, keyName, cancellationToken);
await trasnsferUtility.UploadAsync(filePath, bucket, key, cancellationToken);
upload.State = UploadState.Successful;
successCount++;
logger.LogDebug("Transferred file to S3. Bucket: {BucketName}, KeyName: {KeyName}", bucketName, keyName);
logger.LogDebug("Transferred file to S3. Bucket={Bucket}, Key={Key}", bucket, key);
}
catch (Exception exception)
{
failedCount++;
upload.State = UploadState.Failed;
logger.LogError(exception, "Failed to transfer file to S3. Bucket: {BucketName}, keyName: {keyName}", bucketName, keyName);
logger.LogError(exception, "Failed to transfer file to S3. Bucket={Bucket}, key={key}", bucket, key);
}
}
await database.SaveChangesAsync(cancellationToken);
logger.LogInformation("TransferFiles completed. Bucket: {BucketName}, Route: {Route}, Success: {SuccessCount}, Failed: {FailedCount}", bucketName, route, successCount, failedCount);
logger.LogInformation("TransferFiles completed. Bucket={Bucket}, Route={Route}, Success={SuccessCount}, Failed={FailedCount}", bucket, route, successCount, failedCount);
return Result.Success();
}
public async Task<Result<string>> UploadFileAsync(string filePath, string bucketName, string keyName, CancellationToken cancellationToken)
public async Task<Result<string>> UploadFileAsync(string filePath, string bucket, string key, CancellationToken cancellationToken)
{
try
{
using var fileStream = File.OpenRead(filePath);
var contentType = MimeUtility.GetMimeMapping(filePath);
return await UploadFileAsync(fileStream, contentType, bucketName, keyName, cancellationToken);
return await UploadFileAsync(fileStream, contentType, bucket, key, 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}");
logger.LogError(exception, "Failed to upload file to S3 with bucket={Bucket} and key={Key}", bucket, key);
return Result.Error($"Failed to upload file to S3 with bucket: {bucket} and key: {key}");
}
}
public async Task<Result<string>> UploadFileAsync(Stream sourceStream, string contentType, string bucketName, string keyName, CancellationToken cancellationToken)
public async Task<Result<string>> UploadFileAsync(Stream sourceStream, string contentType, string bucket, string key, CancellationToken cancellationToken)
{
var request = new PutObjectRequest
{
BucketName = bucketName,
BucketName = bucket,
ContentType = contentType,
InputStream = sourceStream,
Key = keyName
Key = key
};
var upload = new Upload
{
Id = Guid.NewGuid(),
BucketName = bucketName,
KeyName = keyName,
Bucket = bucket,
Key = key,
ContentType = contentType
};
await database.Uploads.AddAsync(upload, cancellationToken);
@@ -149,45 +149,45 @@ namespace Musify.Infrastructure.Storage
try
{
var response = await amazonS3.PutObjectAsync(request, cancellationToken);
logger.LogDebug("Uploaded file to S3. Bucket: {BucketName}, Key: {KeyName}", bucketName, keyName);
logger.LogDebug("Uploaded file to S3. Bucket?={Bucket}, Key={Key}", bucket, key);
}
catch (Exception exception)
{
logger.LogError(exception, "Failed to upload file to S3 with bucket name {BucketName} and key name {KeyName}", bucketName, keyName);
logger.LogError(exception, "Failed to upload file to S3 with bucket={Bucket} and key={Key}", bucket, key);
upload.State = UploadState.Failed;
return Result.Error($"Failed to upload file to S3 with bucket name {bucketName} and key name {keyName}");
return Result.Error($"Failed to upload file to S3 with bucket: {bucket} and key: {key}");
}
upload.State = UploadState.Successful;
await database.SaveChangesAsync(cancellationToken);
logger.LogDebug("Saved upload record to database. Bucket: {BucketName}, Key: {KeyName}", bucketName, keyName);
logger.LogDebug("Saved upload record to database. Bucket={Bucket}, Key={Key}", bucket, key);
return Result.Success(keyName);
return Result.Success(key);
}
public async Task<Result> CopyFileAsync(string sourceBucketName, string sourceKeyName, string destinationBucketName, string destinationKeyName,
public async Task<Result> CopyFileAsync(string sourceBucket, string sourceKey, string destinationBucket, string destinationKey,
CancellationToken cancellationToken)
{
var request = new CopyObjectRequest
{
SourceBucket = sourceBucketName,
SourceKey = sourceKeyName,
DestinationBucket = destinationBucketName,
DestinationKey = destinationKeyName
SourceBucket = sourceBucket,
SourceKey = sourceKey,
DestinationBucket = destinationBucket,
DestinationKey = destinationKey
};
try
{
var response = await amazonS3.CopyObjectAsync(request, cancellationToken);
logger.LogInformation("Successfully copied file from S3 with bucket name {SourceBucketName} and key name {SourceKeyName} to bucket name {DestinationBucketName} and key name {DestinationKeyName}",
sourceBucketName, sourceKeyName, destinationBucketName, destinationKeyName);
logger.LogInformation("Successfully copied file from S3 with bucket={SourceBucket} and key={SourceKey} to bucket={DestinationBucket} and key={DestinationKey}",
sourceBucket, sourceKey, destinationBucket, destinationKey);
return Result.Success();
}
catch (Exception exception)
{
logger.LogError(exception, "Failed to copy file from S3 with bucket name {SourceBucketName} and key name {SourceKeyName} to bucket name {DestinationBucketName} and key name {DestinationKeyName}",
sourceBucketName, sourceKeyName, destinationBucketName, destinationKeyName);
return Result.Error($"Failed to copy file from S3 with bucket name {sourceBucketName} and key name {sourceKeyName} to bucket name {destinationBucketName} and key name {destinationKeyName}");
logger.LogError(exception, "Failed to copy file from S3 with bucket={SourceBucket} and key={SourceKey} to bucket={DestinationBucket} and key={DestinationKey}",
sourceBucket, sourceKey, destinationBucket, destinationKey);
return Result.Error($"Failed to copy file from S3 with bucket: {sourceBucket} and key: {sourceKey} to bucket: {destinationBucket} and key: {destinationKey}");
}
}
}