Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,27 @@ private async Task DownloadFile()
break;
}

var response = await policy.ExecuteAsync(async () =>
var transferParameters = new TransferParameters
{
SessionId = SharedFileDefinition.SessionId,
SharedFileDefinition = SharedFileDefinition,
PartNumber = partNumber
};
var downloadLocation = await _fileTransferApiClient.GetDownloadFileStorageLocation(transferParameters);
var storageProvider = downloadLocation.StorageProvider;

var downloadResponse = await policy.ExecuteAsync(async () =>
{
var transferParameters = new TransferParameters
{
SessionId = SharedFileDefinition.SessionId,
SharedFileDefinition = SharedFileDefinition,
PartNumber = partNumber
};
var downloadLocation = await _fileTransferApiClient.GetDownloadFileStorageLocation(transferParameters);

var memoryStream = new MemoryStream();
var downloadStrategy = _strategies[downloadLocation.StorageProvider];
var downloadStrategy = _strategies[storageProvider];
var response = await downloadStrategy.DownloadAsync(memoryStream, downloadLocation, CancellationTokenSource.Token);

DownloadTarget.AddOrReplaceMemoryStream(partNumber, memoryStream);
return response;
});
if (response.IsSuccess)
if (downloadResponse.IsSuccess)
{
await AssertFilePartIsDownloaded(partNumber);
await AssertFilePartIsDownloaded(partNumber, storageProvider);
await _semaphoreSlim.WaitAsync();
try
{
Expand Down Expand Up @@ -166,14 +167,16 @@ private async Task DownloadFile()
}
}

private async Task AssertFilePartIsDownloaded(int partNumber)
private async Task AssertFilePartIsDownloaded(int partNumber, StorageProvider storageProvider)
{
var transferParameters = new TransferParameters
{
SessionId = SharedFileDefinition.SessionId,
SharedFileDefinition = SharedFileDefinition,
PartNumber = partNumber
PartNumber = partNumber,
StorageProvider = storageProvider
};

await _filePartDownloadAsserter.AssertAsync(transferParameters);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public class TransferParameters
public int? TotalParts { get; set; }

public List<string>? ActionsGroupIds { get; set; }

public StorageProvider StorageProvider { get; set; }
}
2 changes: 2 additions & 0 deletions src/ByteSync.ServerCommon/Business/Sessions/SharedFileData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,6 @@ public bool IsPartFullyDownloaded(int partNumber)

return false;
}

public StorageProvider StorageProvider { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public async Task Handle(AssertFilePartIsDownloadedRequest request, Cancellation

if (_transferLocationService.IsSharedFileDefinitionAllowed(sessionMemberData, sharedFileDefinition))
{
await _sharedFilesService.AssertFilePartIsDownloaded(sharedFileDefinition, request.Client, partNumber);
await _sharedFilesService.AssertFilePartIsDownloaded(sharedFileDefinition, request.Client, partNumber, request.TransferParameters.StorageProvider);
}

_logger.LogDebug("File part download asserted for session {SessionId}, file {FileId}, part {PartNumber}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public interface ISharedFilesService

Task AssertUploadIsFinished(SharedFileDefinition sharedFileDefinition, int totalParts, ICollection<string> recipients);

Task AssertFilePartIsDownloaded(SharedFileDefinition sharedFileDefinition, Client client, int partNumber);
Task AssertFilePartIsDownloaded(SharedFileDefinition sharedFileDefinition, Client client, int partNumber, StorageProvider storageProvider);

// Task AssertDownloadIsFinished(SharedFileDefinition sharedFileDefinition, Client client);

Expand Down
39 changes: 33 additions & 6 deletions src/ByteSync.ServerCommon/Services/SharedFilesService.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
ο»Ώusing ByteSync.Common.Business.SharedFiles;
using ByteSync.ServerCommon.Business.Auth;
using ByteSync.ServerCommon.Business.Sessions;
using ByteSync.ServerCommon.Business.Settings;
using ByteSync.ServerCommon.Interfaces.Repositories;
using ByteSync.ServerCommon.Interfaces.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace ByteSync.ServerCommon.Services;

public class SharedFilesService : ISharedFilesService
{
private readonly ISharedFilesRepository _sharedFilesRepository;
private readonly IBlobUrlService _blobUrlService;
private readonly ICloudflareR2UrlService _cloudflareR2UrlService;
private readonly ILogger<SharedFilesService> _logger;
private readonly StorageProvider _storageProvider;

public SharedFilesService(ISharedFilesRepository sharedFilesRepository, IBlobUrlService blobUrlService, ILogger<SharedFilesService> logger)
public SharedFilesService(
ISharedFilesRepository sharedFilesRepository,
IBlobUrlService blobUrlService,
ICloudflareR2UrlService cloudflareR2UrlService,
IOptions<AppSettings> appSettings,
ILogger<SharedFilesService> logger)
{
_sharedFilesRepository = sharedFilesRepository;
_blobUrlService = blobUrlService;
_cloudflareR2UrlService = cloudflareR2UrlService;
_logger = logger;
_storageProvider = appSettings.Value.DefaultStorageProvider;
}
public async Task AssertFilePartIsUploaded(SharedFileDefinition sharedFileDefinition, int partNumber, ICollection<string> recipients)
{
await _sharedFilesRepository.AddOrUpdate(sharedFileDefinition, sharedFileData =>
{
sharedFileData ??= new SharedFileData(sharedFileDefinition, recipients);
sharedFileData ??= new SharedFileData(sharedFileDefinition, recipients)
{
StorageProvider = _storageProvider
};

sharedFileData.UploadedPartsNumbers.Add(partNumber);

Expand All @@ -35,15 +49,18 @@ public async Task AssertUploadIsFinished(SharedFileDefinition sharedFileDefiniti
{
await _sharedFilesRepository.AddOrUpdate(sharedFileDefinition, sharedFileData =>
{
sharedFileData ??= new SharedFileData(sharedFileDefinition, recipients);
sharedFileData ??= new SharedFileData(sharedFileDefinition, recipients)
{
StorageProvider = _storageProvider
};

sharedFileData.TotalParts = totalParts;

return sharedFileData;
});
}

public async Task AssertFilePartIsDownloaded(SharedFileDefinition sharedFileDefinition, Client downloadedBy, int partNumber)
public async Task AssertFilePartIsDownloaded(SharedFileDefinition sharedFileDefinition, Client downloadedBy, int partNumber, StorageProvider storageProvider)
{
bool deleteBlob = false;
bool unregister = false;
Expand Down Expand Up @@ -74,7 +91,12 @@ await _sharedFilesRepository.AddOrUpdate(sharedFileDefinition, sharedFileData =>
{
try
{
await _blobUrlService.DeleteBlob(sharedFileDefinition, partNumber);
await (storageProvider switch
{
StorageProvider.AzureBlobStorage => _blobUrlService.DeleteBlob(sharedFileDefinition, partNumber),
StorageProvider.CloudflareR2 => _cloudflareR2UrlService.DeleteObject(sharedFileDefinition, partNumber),
_ => throw new NotSupportedException($"Storage provider {storageProvider} is not supported")
});
}
catch (Exception ex)
{
Expand Down Expand Up @@ -105,7 +127,12 @@ public async Task ClearSession(string sessionId)
{
try
{
await _blobUrlService.DeleteBlob(sharedFileData.SharedFileDefinition, i);
await (sharedFileData.StorageProvider switch
{
StorageProvider.AzureBlobStorage => _blobUrlService.DeleteBlob(sharedFileData.SharedFileDefinition, i),
StorageProvider.CloudflareR2 => _cloudflareR2UrlService.DeleteObject(sharedFileData.SharedFileDefinition, i),
_ => throw new NotSupportedException($"Storage provider {sharedFileData.StorageProvider} is not supported")
});
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public void Setup()
}

[Test]
public async Task Handle_ValidRequest_AssertsFilePartIsDownloaded()
[TestCase(StorageProvider.AzureBlobStorage)]
[TestCase(StorageProvider.CloudflareR2)]
public async Task Handle_ValidRequest_AssertsFilePartIsDownloaded(StorageProvider storageProvider)
{
// Arrange
var sessionId = "session1";
Expand All @@ -46,7 +48,8 @@ public async Task Handle_ValidRequest_AssertsFilePartIsDownloaded()
{
SessionId = sessionId,
SharedFileDefinition = sharedFileDefinition,
PartNumber = partNumber
PartNumber = partNumber,
StorageProvider = storageProvider
};
var request = new AssertFilePartIsDownloadedRequest(sessionId, client, transferParameters);

Expand All @@ -59,7 +62,7 @@ public async Task Handle_ValidRequest_AssertsFilePartIsDownloaded()
.Returns(true);

// Mock the shared files service
A.CallTo(() => _mockSharedFilesService.AssertFilePartIsDownloaded(sharedFileDefinition, client, partNumber))
A.CallTo(() => _mockSharedFilesService.AssertFilePartIsDownloaded(sharedFileDefinition, client, partNumber, storageProvider))
.Returns(Task.CompletedTask);

// Act
Expand All @@ -70,10 +73,14 @@ public async Task Handle_ValidRequest_AssertsFilePartIsDownloaded()
.MustHaveHappenedOnceExactly();
A.CallTo(() => _mockTransferLocationService.IsSharedFileDefinitionAllowed(mockSessionMember, sharedFileDefinition))
.MustHaveHappenedOnceExactly();
A.CallTo(() => _mockSharedFilesService.AssertFilePartIsDownloaded(sharedFileDefinition, client, partNumber, storageProvider))
.MustHaveHappenedOnceExactly();
}

[Test]
public async Task Handle_WhenServiceThrowsException_PropagatesException()
[TestCase(StorageProvider.AzureBlobStorage)]
[TestCase(StorageProvider.CloudflareR2)]
public async Task Handle_WhenServiceThrowsException_PropagatesException(StorageProvider storageProvider)
{
// Arrange
var sessionId = "session1";
Expand All @@ -86,7 +93,8 @@ public async Task Handle_WhenServiceThrowsException_PropagatesException()
{
SessionId = sessionId,
SharedFileDefinition = sharedFileDefinition,
PartNumber = partNumber
PartNumber = partNumber,
StorageProvider = storageProvider
};
var request = new AssertFilePartIsDownloadedRequest(sessionId, client, transferParameters);

Expand Down
Loading