From ebf5e1b3063b5dd06c4baee16d1ea9970b77fe72 Mon Sep 17 00:00:00 2001 From: Radekor500 Date: Sat, 24 Feb 2024 14:16:03 +0100 Subject: [PATCH] setup chunk directory on upload creation and throw error if it doesnt exist --- .../Handlers/CreateSecureUploadHandler.cs | 7 ++++- .../Services/IFileService.cs | 2 ++ .../MissingUploadDirectoryException.cs | 10 +++++++ .../Services/FileService.cs | 29 ++++++++++++------- .../CreateSecureUploadHandlerTests.cs | 4 ++- 5 files changed, 39 insertions(+), 13 deletions(-) create mode 100644 SecureSend.Infrastructure/Exceptions/MissingUploadDirectoryException.cs diff --git a/SecureSend.Application/Commands/Handlers/CreateSecureUploadHandler.cs b/SecureSend.Application/Commands/Handlers/CreateSecureUploadHandler.cs index e33aead..1c43c7a 100644 --- a/SecureSend.Application/Commands/Handlers/CreateSecureUploadHandler.cs +++ b/SecureSend.Application/Commands/Handlers/CreateSecureUploadHandler.cs @@ -16,16 +16,20 @@ public sealed class CreateSecureUploadHandler: ICommandHandler _fileStorageOptions; private readonly IUploadSizeTrackerService _sizeTrackerService; + private readonly IFileService _fileService; public CreateSecureUploadHandler(ISecureSendUploadRepository secureSendUploadRepository, ISecureSendUploadFactory secureSendUploadFactory, - ISecureUploadReadService secureUploadReadService, IOptions fileStorageOptions, IUploadSizeTrackerService sizeTrackerService) + ISecureUploadReadService secureUploadReadService, + IOptions fileStorageOptions, IUploadSizeTrackerService sizeTrackerService, + IFileService fileService) { _secureSendUploadRepository = secureSendUploadRepository; _secureSendUploadFactory = secureSendUploadFactory; _secureUploadReadService = secureUploadReadService; _fileStorageOptions = fileStorageOptions; _sizeTrackerService = sizeTrackerService; + _fileService = fileService; } public async Task Handle (CreateSecureUpload command, CancellationToken cancellationToken) @@ -42,6 +46,7 @@ public async Task Handle (CreateSecureUpload command, CancellationToken ca if (persisted is not null && persisted != Guid.Empty) throw new UploadAlreadyExistsException(persisted.Value); _sizeTrackerService.TryUpdateUploadSize(command.uploadId, 0); var secureUpload = _secureSendUploadFactory.CreateSecureSendUpload(command.uploadId, expiryDate, false, command.password); + _fileService.SetupUploadDirectory(command.uploadId); await _secureSendUploadRepository.AddAsync(secureUpload, cancellationToken); return Unit.Value; diff --git a/SecureSend.Application/Services/IFileService.cs b/SecureSend.Application/Services/IFileService.cs index e571546..0dfc422 100644 --- a/SecureSend.Application/Services/IFileService.cs +++ b/SecureSend.Application/Services/IFileService.cs @@ -14,5 +14,7 @@ public interface IFileService void RemoveUpload(Guid uploadId); void RemoveFileFromUpload(Guid uploadId, string fileName); double GetCurrentUploadDirectorySize(); + + void SetupUploadDirectory(Guid uploadId); } } diff --git a/SecureSend.Infrastructure/Exceptions/MissingUploadDirectoryException.cs b/SecureSend.Infrastructure/Exceptions/MissingUploadDirectoryException.cs new file mode 100644 index 0000000..5aa7316 --- /dev/null +++ b/SecureSend.Infrastructure/Exceptions/MissingUploadDirectoryException.cs @@ -0,0 +1,10 @@ +using SecureSend.Domain.Exceptions; + +namespace SecureSend.Infrastructure.Exceptions; + +public class MissingUploadDirectoryException: SecureSendException +{ + public MissingUploadDirectoryException(Guid uploadId) : base($"Missing directory for upload: {uploadId}. Upload has to be setup first.") + { + } +} \ No newline at end of file diff --git a/SecureSend.Infrastructure/Services/FileService.cs b/SecureSend.Infrastructure/Services/FileService.cs index 8c424b2..5ad3d62 100644 --- a/SecureSend.Infrastructure/Services/FileService.cs +++ b/SecureSend.Infrastructure/Services/FileService.cs @@ -2,6 +2,7 @@ using SecureSend.Application.Services; using SecureSend.Domain.ValueObjects; using SecureSend.Application.Options; +using SecureSend.Infrastructure.Exceptions; namespace SecureSend.Infrastructure.Services { @@ -17,7 +18,7 @@ public FileService(IOptions fileStorageOptions) public FileStream? DownloadFile(Guid uploadId, string fileName) { - var directory = GetDirectory(uploadId); + var directory = GetUploadDirectory(uploadId); var file = directory?.GetFiles().FirstOrDefault(f => f.Name == fileName); @@ -26,16 +27,15 @@ public FileService(IOptions fileStorageOptions) public async Task SaveChunkToDisk(SecureUploadChunk chunk, Guid uploadId) { - var directory = GetOrCreateDirectory(uploadId, chunk.ChunkDirectory); + var directory = GetChunkDirectory(uploadId, chunk.ChunkDirectory); await using var output = System.IO.File.OpenWrite($"{directory.FullName}/{chunk.ChunkName}"); await chunk.Chunk.CopyToAsync(output); } public async Task MergeFiles(Guid uploadId, IEnumerable chunkFiles, string chunkDirectory, string randomFileName) { - - - var dir = GetOrCreateDirectory(uploadId, chunkDirectory); + + var dir = GetChunkDirectory(uploadId, chunkDirectory); var mergedFilePath = Path.Combine(dir.Parent!.FullName, randomFileName); await using (var mergedFile = new FileStream(mergedFilePath, FileMode.Create)) @@ -51,7 +51,7 @@ public async Task MergeFiles(Guid uploadId, IEnumerable chunkFiles, stri public IEnumerable GetChunksList(Guid uploadId, string chunkDirectory) { - var directory = GetOrCreateDirectory(uploadId, chunkDirectory).FullName; + var directory = GetChunkDirectory(uploadId, chunkDirectory).FullName; var chunkFiles = Directory.GetFiles(directory) .Select(x => Path.GetFileName(x)) .OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f).Split('_')[0])) @@ -59,12 +59,14 @@ public IEnumerable GetChunksList(Guid uploadId, string chunkDirectory) return chunkFiles; } - private DirectoryInfo GetOrCreateDirectory(Guid uploadId, string chunkDirectory) + private DirectoryInfo GetChunkDirectory(Guid uploadId, string chunkDirectory) { - return System.IO.Directory.CreateDirectory($"{_fileStorageOptions.Value.Path}/{uploadId}/{chunkDirectory}"); + var uploadDirectory = GetUploadDirectory(uploadId); + if (uploadDirectory is null) throw new MissingUploadDirectoryException(uploadId); + return Directory.CreateDirectory($"{_fileStorageOptions.Value.Path}/{uploadId}/{chunkDirectory}"); } - private DirectoryInfo? GetDirectory(Guid uploadId) + private DirectoryInfo? GetUploadDirectory(Guid uploadId) { if (Directory.Exists($"{_fileStorageOptions.Value.Path}/{uploadId}")) return Directory.CreateDirectory($"{_fileStorageOptions.Value.Path}/{uploadId}"); return null; @@ -72,14 +74,14 @@ private DirectoryInfo GetOrCreateDirectory(Guid uploadId, string chunkDirectory) public void RemoveUpload(Guid uploadId) { - var directory = GetDirectory(uploadId); + var directory = GetUploadDirectory(uploadId); if (directory != null) Directory.Delete(directory.FullName, true); } public void RemoveFileFromUpload(Guid uploadId, string fileName) { - var fileDir = GetDirectory(uploadId)?.GetDirectories() + var fileDir = GetUploadDirectory(uploadId)?.GetDirectories() .FirstOrDefault(x => x.Name == Path.GetFileNameWithoutExtension(fileName)); if (fileDir is not null) Directory.Delete(fileDir.FullName, true); } @@ -89,5 +91,10 @@ public double GetCurrentUploadDirectorySize() var di = new DirectoryInfo(_fileStorageOptions.Value.Path); return di.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length); } + + public void SetupUploadDirectory(Guid uploadId) + { + Directory.CreateDirectory($"{_fileStorageOptions.Value.Path}/{uploadId}"); + } } } diff --git a/SecureSend.Test/Application/Handlers/CreateSecureUploadHandlerTests.cs b/SecureSend.Test/Application/Handlers/CreateSecureUploadHandlerTests.cs index 057ab86..1f6efb9 100644 --- a/SecureSend.Test/Application/Handlers/CreateSecureUploadHandlerTests.cs +++ b/SecureSend.Test/Application/Handlers/CreateSecureUploadHandlerTests.cs @@ -21,6 +21,7 @@ public class CreateSecureUploadHandlerTests private readonly ICommandHandler _commandHandler; private readonly Mock> _fileStorageOptions; private readonly Mock _sizeTrackerService; + private readonly Mock _fileService; private readonly FileStorageOptions _sampleOptions = new FileStorageOptions() { @@ -35,8 +36,9 @@ public CreateSecureUploadHandlerTests() _secureUploadReadService = new Mock(); _fileStorageOptions = new Mock>(); _sizeTrackerService = new Mock(); + _fileService = new Mock(); _commandHandler = new CreateSecureUploadHandler(_secureSendUploadRepository.Object, _secureSendUploadFactory.Object, - _secureUploadReadService.Object, _fileStorageOptions.Object, _sizeTrackerService.Object); + _secureUploadReadService.Object, _fileStorageOptions.Object, _sizeTrackerService.Object, _fileService.Object); }