Skip to content

Commit

Permalink
setup chunk directory on upload creation and throw error if it doesnt…
Browse files Browse the repository at this point in the history
… exist
  • Loading branch information
radek00 committed Feb 24, 2024
1 parent c3b9049 commit ebf5e1b
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,20 @@ public sealed class CreateSecureUploadHandler: ICommandHandler<CreateSecureUploa
private readonly ISecureUploadReadService _secureUploadReadService;
private readonly IOptions<FileStorageOptions> _fileStorageOptions;
private readonly IUploadSizeTrackerService _sizeTrackerService;
private readonly IFileService _fileService;

public CreateSecureUploadHandler(ISecureSendUploadRepository secureSendUploadRepository,
ISecureSendUploadFactory secureSendUploadFactory,
ISecureUploadReadService secureUploadReadService, IOptions<FileStorageOptions> fileStorageOptions, IUploadSizeTrackerService sizeTrackerService)
ISecureUploadReadService secureUploadReadService,
IOptions<FileStorageOptions> fileStorageOptions, IUploadSizeTrackerService sizeTrackerService,
IFileService fileService)
{
_secureSendUploadRepository = secureSendUploadRepository;
_secureSendUploadFactory = secureSendUploadFactory;
_secureUploadReadService = secureUploadReadService;
_fileStorageOptions = fileStorageOptions;
_sizeTrackerService = sizeTrackerService;
_fileService = fileService;
}

public async Task<Unit> Handle (CreateSecureUpload command, CancellationToken cancellationToken)
Expand All @@ -42,6 +46,7 @@ public async Task<Unit> 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;

Expand Down
2 changes: 2 additions & 0 deletions SecureSend.Application/Services/IFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ public interface IFileService
void RemoveUpload(Guid uploadId);
void RemoveFileFromUpload(Guid uploadId, string fileName);
double GetCurrentUploadDirectorySize();

void SetupUploadDirectory(Guid uploadId);
}
}
Original file line number Diff line number Diff line change
@@ -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.")
{
}
}
29 changes: 18 additions & 11 deletions SecureSend.Infrastructure/Services/FileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using SecureSend.Application.Services;
using SecureSend.Domain.ValueObjects;
using SecureSend.Application.Options;
using SecureSend.Infrastructure.Exceptions;

namespace SecureSend.Infrastructure.Services
{
Expand All @@ -17,7 +18,7 @@ public FileService(IOptions<FileStorageOptions> 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);

Expand All @@ -26,16 +27,15 @@ public FileService(IOptions<FileStorageOptions> 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<string> 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))
Expand All @@ -51,35 +51,37 @@ public async Task MergeFiles(Guid uploadId, IEnumerable<string> chunkFiles, stri

public IEnumerable<string> 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]))
.ToList();
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;
}

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);
}
Expand All @@ -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}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class CreateSecureUploadHandlerTests
private readonly ICommandHandler<CreateSecureUpload, Unit> _commandHandler;
private readonly Mock<IOptions<FileStorageOptions>> _fileStorageOptions;
private readonly Mock<IUploadSizeTrackerService> _sizeTrackerService;
private readonly Mock<IFileService> _fileService;

private readonly FileStorageOptions _sampleOptions = new FileStorageOptions()
{
Expand All @@ -35,8 +36,9 @@ public CreateSecureUploadHandlerTests()
_secureUploadReadService = new Mock<ISecureUploadReadService>();
_fileStorageOptions = new Mock<IOptions<FileStorageOptions>>();
_sizeTrackerService = new Mock<IUploadSizeTrackerService>();
_fileService = new Mock<IFileService>();
_commandHandler = new CreateSecureUploadHandler(_secureSendUploadRepository.Object, _secureSendUploadFactory.Object,
_secureUploadReadService.Object, _fileStorageOptions.Object, _sizeTrackerService.Object);
_secureUploadReadService.Object, _fileStorageOptions.Object, _sizeTrackerService.Object, _fileService.Object);
}


Expand Down

0 comments on commit ebf5e1b

Please sign in to comment.