Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -64,7 +64,7 @@ private async Task<UploadResult> ReceiveNewFileStreamInternal(Guid? driveId)
{
try
{
await driveUploadService.CleanupTempFiles(WebOdinContext);
await driveUploadService.CleanupStagingFiles(WebOdinContext);
}
catch (Exception e)
{
Expand Down Expand Up @@ -190,7 +190,7 @@ await updateWriter.AddThumbnail(thumbnailUploadKey, contentTypeFromMultipartSect
{
try
{
await updateWriter.CleanupTempFiles(WebOdinContext);
await updateWriter.CleanupStagingFiles(WebOdinContext);
}
catch (Exception e)
{
Expand Down Expand Up @@ -317,7 +317,7 @@ protected async Task<UploadPayloadResult> ReceivePayloadStream()
{
try
{
await writer.CleanupTempFiles(WebOdinContext);
await writer.CleanupStagingFiles(WebOdinContext);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public async Task<TransitResult> SendFile()
{
try
{
await fileSystemWriter.CleanupTempFiles(WebOdinContext);
await fileSystemWriter.CleanupStagingFiles(WebOdinContext);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,55 @@ public class OwnerDriveStorageController(
private readonly ILogger<OwnerDriveStorageController> _logger = logger;

/// <summary>
/// Indicates if the specified TempFile exists. This is used for testing only
/// Indicates if the specified upload temp file exists. This is used for testing only
/// </summary>
[SwaggerOperation(Tags = [ControllerConstants.OwnerDrive])]
[HttpGet("temp-file-exists")]
public async Task<bool> TempFileExists([FromQuery] Guid fileId,
[HttpGet("upload-file-exists")]
public async Task<bool> UploadFileExists([FromQuery] Guid fileId,
[FromQuery] Guid alias,
[FromQuery] Guid type,
[FromQuery] TempStorageType storageType,
[FromQuery] string extension)
{
var tempFile = new TempFile()
var file = MapToInternalFile(new ExternalFileIdentifier()
{
File = MapToInternalFile(new ExternalFileIdentifier()
FileId = fileId,
TargetDrive = new TargetDrive()
{
FileId = fileId,
TargetDrive = new TargetDrive()
{
Alias = alias,
Type = type
}
}),
StorageType = storageType
};
Alias = alias,
Type = type
}
});

var result = await this.GetHttpFileSystemResolver()
return await this.GetHttpFileSystemResolver()
.ResolveFileSystem()
.Storage
.TempFileExists(tempFile, extension, WebOdinContext);
.UploadFileExists(file, extension, WebOdinContext);
}

return result;
/// <summary>
/// Indicates if the specified inbox temp file exists. This is used for testing only
/// </summary>
[SwaggerOperation(Tags = [ControllerConstants.OwnerDrive])]
[HttpGet("inbox-file-exists")]
public async Task<bool> InboxFileExists([FromQuery] Guid fileId,
[FromQuery] Guid alias,
[FromQuery] Guid type,
[FromQuery] string extension)
{
var file = MapToInternalFile(new ExternalFileIdentifier()
{
FileId = fileId,
TargetDrive = new TargetDrive()
{
Alias = alias,
Type = type
}
});

return await this.GetHttpFileSystemResolver()
.ResolveFileSystem()
.Storage
.InboxFileExists(file, extension, WebOdinContext);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public async Task<PeerTransferResponse> ReceiveIncomingUpdate()
{
if (null != _fileUpdateService)
{
await _fileUpdateService.CleanupTempFiles(uploadedPayloads, WebOdinContext);
await _fileUpdateService.CleanupStagingFiles(uploadedPayloads, WebOdinContext);
}
}
catch (Exception e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public async Task<PeerTransferResponse> ReceiveIncomingTransfer()
{
if (null != _incomingTransferService)
{
await _incomingTransferService.CleanupTempFiles(uploadedPayloads, WebOdinContext);
await _incomingTransferService.CleanupStagingFiles(uploadedPayloads, WebOdinContext);
}
}
catch (Exception e)
Expand Down
1 change: 1 addition & 0 deletions src/apps/Odin.Hosting/TenantServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ internal static ContainerBuilder ConfigureTenantServices(

cb.RegisterType<LongTermStorageManager>().InstancePerLifetimeScope();
cb.RegisterType<UploadStorageManager>().InstancePerLifetimeScope();
cb.RegisterType<InboxStorageManager>().InstancePerLifetimeScope();
// cb.RegisterType<OrphanTestUtil>().InstancePerLifetimeScope();

cb.RegisterType<DriveAclAuthorizationService>().As<IDriveAclAuthorizationService>().InstancePerLifetimeScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class FileAddedNotification : IClientNotification

public OdinId Sender { get; set; }

public ExternalFileIdentifier TempFile { get; set; }
public ExternalFileIdentifier File { get; set; }

public string GetClientData()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Odin.Core.Exceptions;
using Odin.Services.Base;
using Odin.Services.Drives.FileSystem.Base;
using Directory = System.IO.Directory;
Expand All @@ -29,16 +28,28 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)

try
{
TempFolderCleanUp.Execute(
UploadFolderCleanUp.Execute(
logger,
tenantContext.TenantPathManager.TempPath,
tenantContext.TenantPathManager.UploadDrivesPath,
uploadAgeThreshold,
stoppingToken);
}
catch (Exception e)
{
logger.LogError(e, "UploadFolderCleanUp: {message}", e.Message);
}

try
{
InboxFolderCleanUp.Execute(
logger,
tenantContext.TenantPathManager.InboxDrivesPath,
inboxAgeThreshold,
stoppingToken);
}
catch (Exception e)
{
logger.LogError(e, "TempFolderCleanUpBackgroundService: {message}", e.Message);
logger.LogError(e, "InboxFolderCleanUp: {message}", e.Message);
}

var interval = TimeSpan.FromHours(24);
Expand All @@ -50,57 +61,109 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)

//

public static class TempFolderCleanUp
public static class UploadFolderCleanUp
{
public static void Execute(
ILogger logger,
string tempFolder,
TimeSpan uploadAgeThreshold,
TimeSpan inboxAgeThreshold,
string uploadDrivesPath,
TimeSpan ageThreshold,
CancellationToken stoppingToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(tempFolder, nameof(tempFolder));
if (!Directory.Exists(uploadDrivesPath))
{
return;
}

if (uploadAgeThreshold <= TimeSpan.Zero)
var drives = Directory.GetDirectories(uploadDrivesPath);
foreach (var drive in drives)
{
throw new ArgumentException("Upload age threshold must be positive", nameof(uploadAgeThreshold));
if (stoppingToken.IsCancellationRequested)
{
return;
}

var uploadsPath = Path.Combine(drive, TenantPathManager.UploadFolder);
CleanUp(logger, uploadsPath, ageThreshold, stoppingToken);
}
}

if (inboxAgeThreshold <= TimeSpan.Zero)
//

private static void CleanUp(ILogger logger, string folder, TimeSpan threshold, CancellationToken stoppingToken)
{
if (!Directory.Exists(folder))
{
throw new ArgumentException("Inbox age threshold must be positive", nameof(inboxAgeThreshold));
return;
}

if (!Directory.Exists(tempFolder))
logger.LogDebug("{service} is scanning {folder}", nameof(UploadFolderCleanUp), folder);

try
{
throw new OdinSystemException($"Temp folder {tempFolder} does not exist");
var subDirectories = Directory.GetDirectories(folder);
if (subDirectories.Length > 0)
{
logger.LogError("Illegal subdirectories detected in {Folder}", folder);
}

var cutoffTime = DateTime.UtcNow.Subtract(threshold);
var files = Directory.GetFiles(folder);

foreach (var file in files)
{
if (stoppingToken.IsCancellationRequested)
{
return;
}

try
{
var fileInfo = new FileInfo(file);
if (fileInfo.LastWriteTimeUtc < cutoffTime)
{
logger.LogDebug("UploadFolderCleanUp: deleting file {file}", file);
File.Delete(file);
}
}
catch (Exception e)
{
logger.LogError(e, "UploadFolderCleanUp({file}): {message}", file, e.Message);
}
}
}
catch (Exception e)
{
logger.LogError(e, "UploadFolderCleanUp({folder}): {message}", folder, e.Message);
}
}
}

var drivesFolder = Path.Combine(tempFolder, TenantPathManager.DrivesFolder);
if (!Directory.Exists(drivesFolder))
//

// NOTE: This class is likely dead code in the future — inbox files are not expected to be cleaned up
public static class InboxFolderCleanUp
{
public static void Execute(
ILogger logger,
string inboxDrivesPath,
TimeSpan ageThreshold,
CancellationToken stoppingToken = default)
{
if (!Directory.Exists(inboxDrivesPath))
{
return;
}

var drives = Directory.GetDirectories(drivesFolder);
var drives = Directory.GetDirectories(inboxDrivesPath);
foreach (var drive in drives)
{
if (stoppingToken.IsCancellationRequested)
{
return;
}

if (!stoppingToken.IsCancellationRequested)
{
var uploadsPath = Path.Combine(drive, TenantPathManager.UploadFolder);
CleanUp(logger, uploadsPath, uploadAgeThreshold, stoppingToken);
}

if (!stoppingToken.IsCancellationRequested)
{
var inboxPath = Path.Combine(drive, TenantPathManager.InboxFolder);
CleanUp(logger, inboxPath, inboxAgeThreshold, stoppingToken);
}
var inboxPath = Path.Combine(drive, TenantPathManager.InboxFolder);
CleanUp(logger, inboxPath, ageThreshold, stoppingToken);
}
}

Expand All @@ -113,7 +176,7 @@ private static void CleanUp(ILogger logger, string folder, TimeSpan threshold, C
return;
}

logger.LogDebug("{service} is scanning {folder}", nameof(TempFolderCleanUp), folder);
logger.LogDebug("{service} is scanning {folder}", nameof(InboxFolderCleanUp), folder);

try
{
Expand All @@ -138,20 +201,19 @@ private static void CleanUp(ILogger logger, string folder, TimeSpan threshold, C
var fileInfo = new FileInfo(file);
if (fileInfo.LastWriteTimeUtc < cutoffTime)
{
logger.LogDebug("TempFolderCleanUp: deleting file {file}", file);
logger.LogDebug("InboxFolderCleanUp: deleting file {file}", file);
File.Delete(file);
}
}
catch (Exception e)
{
logger.LogError(e, "TempFolderCleanUp({file}): {message}", file, e.Message);
logger.LogError(e, "InboxFolderCleanUp({file}): {message}", file, e.Message);
}
}
}
catch (Exception e)
{
logger.LogError(e, "TempFolderCleanUp({folder}): {message}", folder, e.Message);
logger.LogError(e, "InboxFolderCleanUp({folder}): {message}", folder, e.Message);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -220,14 +220,10 @@ private async Task<PeerTransferResponse> RouteFeedRequestToInboxAsync(UpdateFeed
logger.LogDebug("Found feed drive id {id}", feedDriveId);

// Write to temp file
var tempFile = new TempFile()
{
File = await fileSystem.Storage.CreateInternalFileId(feedDriveId, odinContext),
StorageType = TempStorageType.Inbox
};
var file = await fileSystem.Storage.CreateInternalFileId(feedDriveId, odinContext);

var stream = OdinSystemSerializer.Serialize(request.FileMetadata).ToUtf8ByteArray().ToMemoryStream();
await fileSystem.Storage.WriteTempStream(tempFile, MultipartHostTransferParts.Metadata.ToString().ToLower(), stream,
await fileSystem.Storage.WriteInboxStream(file, MultipartHostTransferParts.Metadata.ToString().ToLower(), stream,
odinContext);
await stream.DisposeAsync();

Expand All @@ -239,8 +235,8 @@ await fileSystem.Storage.WriteTempStream(tempFile, MultipartHostTransferParts.Me
Sender = odinContext.GetCallerOdinIdOrFail(),
InstructionType = TransferInstructionType.SaveFile,

FileId = tempFile.File.FileId,
DriveId = tempFile.File.DriveId,
FileId = file.FileId,
DriveId = file.DriveId,
GlobalTransitId = request.FileMetadata.GlobalTransitId.GetValueOrDefault(),
FileSystemType = FileSystemType.Standard, //comments are never distributed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ ENABLE WHEN WE CREATE A DIRECTORY AND NIBBLES ON DRIVE CREATION

public async Task VerifyDriveDirectoriesTemp(bool cleanup)
{
var rootpath = _tenantPathManager.TempDrivesPath;
var rootpath = _tenantPathManager.UploadDrivesPath;

if (Directory.Exists(rootpath))
{
Expand Down
Loading
Loading