🧱 File service basis
This commit is contained in:
		| @@ -66,9 +66,4 @@ | ||||
|     <ItemGroup> | ||||
|       <ProjectReference Include="..\DysonNetwork.Shared\DysonNetwork.Shared.csproj" /> | ||||
|     </ItemGroup> | ||||
|  | ||||
|     <ItemGroup> | ||||
|       <Compile Remove="Storage\FileReferenceServiceGrpc.cs" /> | ||||
|     </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|   | ||||
							
								
								
									
										127
									
								
								DysonNetwork.Drive/Storage/FileReferenceServiceGrpc.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								DysonNetwork.Drive/Storage/FileReferenceServiceGrpc.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| using System.Threading.Tasks; | ||||
| using DysonNetwork.Shared.Proto; | ||||
| using Google.Protobuf.WellKnownTypes; | ||||
| using Grpc.Core; | ||||
| using NodaTime; | ||||
| using Duration = NodaTime.Duration; | ||||
|  | ||||
| namespace DysonNetwork.Drive.Storage | ||||
| { | ||||
|     public class FileReferenceServiceGrpc(FileReferenceService fileReferenceService) : Shared.Proto.FileReferenceService.FileReferenceServiceBase | ||||
|     { | ||||
|         public override async Task<Shared.Proto.CloudFileReference> CreateReference(CreateReferenceRequest request, ServerCallContext context) | ||||
|         { | ||||
|             Instant? expiredAt = null; | ||||
|             if (request.ExpiredAt != null) | ||||
|             { | ||||
|                 expiredAt = Instant.FromUnixTimeSeconds(request.ExpiredAt.Seconds); | ||||
|             } | ||||
|             else if (request.Duration != null) | ||||
|             { | ||||
|                 expiredAt = SystemClock.Instance.GetCurrentInstant() + Duration.FromTimeSpan(request.Duration.ToTimeSpan()); | ||||
|             } | ||||
|  | ||||
|             var reference = await fileReferenceService.CreateReferenceAsync( | ||||
|                 request.FileId, | ||||
|                 request.Usage, | ||||
|                 request.ResourceId, | ||||
|                 expiredAt | ||||
|             ); | ||||
|             return reference.ToProtoValue(); | ||||
|         } | ||||
|  | ||||
|         public override async Task<GetReferencesResponse> GetReferences(GetReferencesRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var references = await fileReferenceService.GetReferencesAsync(request.FileId); | ||||
|             var response = new GetReferencesResponse(); | ||||
|             response.References.AddRange(references.Select(r => r.ToProtoValue())); | ||||
|             return response; | ||||
|         } | ||||
|  | ||||
|         public override async Task<GetReferenceCountResponse> GetReferenceCount(GetReferenceCountRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var count = await fileReferenceService.GetReferenceCountAsync(request.FileId); | ||||
|             return new GetReferenceCountResponse { Count = count }; | ||||
|         } | ||||
|  | ||||
|         public override async Task<GetReferencesResponse> GetResourceReferences(GetResourceReferencesRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var references = await fileReferenceService.GetResourceReferencesAsync(request.ResourceId, request.Usage); | ||||
|             var response = new GetReferencesResponse(); | ||||
|             response.References.AddRange(references.Select(r => r.ToProtoValue())); | ||||
|             return response; | ||||
|         } | ||||
|  | ||||
|         public override async Task<GetResourceFilesResponse> GetResourceFiles(GetResourceFilesRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var files = await fileReferenceService.GetResourceFilesAsync(request.ResourceId, request.Usage); | ||||
|             var response = new GetResourceFilesResponse(); | ||||
|             response.Files.AddRange(files.Select(f => f.ToProtoValue())); | ||||
|             return response; | ||||
|         } | ||||
|  | ||||
|         public override async Task<DeleteResourceReferencesResponse> DeleteResourceReferences(DeleteResourceReferencesRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var deletedCount = await fileReferenceService.DeleteResourceReferencesAsync(request.ResourceId, request.Usage); | ||||
|             return new DeleteResourceReferencesResponse { DeletedCount = deletedCount }; | ||||
|         } | ||||
|  | ||||
|         public override async Task<DeleteReferenceResponse> DeleteReference(DeleteReferenceRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var success = await fileReferenceService.DeleteReferenceAsync(Guid.Parse(request.ReferenceId)); | ||||
|             return new DeleteReferenceResponse { Success = success }; | ||||
|         } | ||||
|  | ||||
|         public override async Task<UpdateResourceFilesResponse> UpdateResourceFiles(UpdateResourceFilesRequest request, ServerCallContext context) | ||||
|         { | ||||
|             Instant? expiredAt = null; | ||||
|             if (request.ExpiredAt != null) | ||||
|             { | ||||
|                 expiredAt = Instant.FromUnixTimeSeconds(request.ExpiredAt.Seconds); | ||||
|             } | ||||
|             else if (request.Duration != null) | ||||
|             { | ||||
|                 expiredAt = SystemClock.Instance.GetCurrentInstant() + Duration.FromTimeSpan(request.Duration.ToTimeSpan()); | ||||
|             } | ||||
|  | ||||
|             var references = await fileReferenceService.UpdateResourceFilesAsync( | ||||
|                 request.ResourceId, | ||||
|                 request.FileIds, | ||||
|                 request.Usage, | ||||
|                 expiredAt | ||||
|             ); | ||||
|             var response = new UpdateResourceFilesResponse(); | ||||
|             response.References.AddRange(references.Select(r => r.ToProtoValue())); | ||||
|             return response; | ||||
|         } | ||||
|  | ||||
|         public override async Task<SetReferenceExpirationResponse> SetReferenceExpiration(SetReferenceExpirationRequest request, ServerCallContext context) | ||||
|         { | ||||
|             Instant? expiredAt = null; | ||||
|             if (request.ExpiredAt != null) | ||||
|             { | ||||
|                 expiredAt = Instant.FromUnixTimeSeconds(request.ExpiredAt.Seconds); | ||||
|             } | ||||
|             else if (request.Duration != null) | ||||
|             { | ||||
|                 expiredAt = SystemClock.Instance.GetCurrentInstant() + Duration.FromTimeSpan(request.Duration.ToTimeSpan()); | ||||
|             } | ||||
|  | ||||
|             var success = await fileReferenceService.SetReferenceExpirationAsync(Guid.Parse(request.ReferenceId), expiredAt); | ||||
|             return new SetReferenceExpirationResponse { Success = success }; | ||||
|         } | ||||
|  | ||||
|         public override async Task<SetFileReferencesExpirationResponse> SetFileReferencesExpiration(SetFileReferencesExpirationRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var expiredAt = Instant.FromUnixTimeSeconds(request.ExpiredAt.Seconds); | ||||
|             var updatedCount = await fileReferenceService.SetFileReferencesExpirationAsync(request.FileId, expiredAt); | ||||
|             return new SetFileReferencesExpirationResponse { UpdatedCount = updatedCount }; | ||||
|         } | ||||
|  | ||||
|         public override async Task<HasFileReferencesResponse> HasFileReferences(HasFileReferencesRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var hasReferences = await fileReferenceService.HasFileReferencesAsync(request.FileId); | ||||
|             return new HasFileReferencesResponse { HasReferences = hasReferences }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										175
									
								
								DysonNetwork.Drive/Storage/FileServiceGrpc.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								DysonNetwork.Drive/Storage/FileServiceGrpc.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | ||||
| using System.Threading.Tasks; | ||||
| using DysonNetwork.Shared.Proto; | ||||
| using Google.Protobuf.WellKnownTypes; | ||||
| using Grpc.Core; | ||||
|  | ||||
| namespace DysonNetwork.Drive.Storage | ||||
| { | ||||
|     public class FileServiceGrpc(FileService fileService) : Shared.Proto.FileService.FileServiceBase | ||||
|     { | ||||
|         public override async Task<Shared.Proto.CloudFile> GetFile(GetFileRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var file = await fileService.GetFileAsync(request.Id); | ||||
|             return file?.ToProtoValue() ?? throw new RpcException(new Status(StatusCode.NotFound, "File not found")); | ||||
|         } | ||||
|  | ||||
|         public override async Task<Shared.Proto.CloudFile> UpdateFile(UpdateFileRequest request, ServerCallContext context) | ||||
|         { | ||||
|             // Assuming UpdateFileAsync exists in FileService and handles the update_mask | ||||
|             // This is a placeholder, as the current FileService.cs doesn't have a direct UpdateFile method | ||||
|             // You might need to implement this logic in FileService based on your needs. | ||||
|             // For now, we'll just return the requested file. | ||||
|             var file = await fileService.GetFileAsync(request.File.Id); | ||||
|             if (file == null) | ||||
|             { | ||||
|                 throw new RpcException(new Status(StatusCode.NotFound, "File not found")); | ||||
|             } | ||||
|  | ||||
|             // Apply updates from request.File to 'file' based on request.UpdateMask | ||||
|             // This part requires more detailed implementation based on how you want to handle partial updates. | ||||
|             return file.ToProtoValue(); | ||||
|         } | ||||
|  | ||||
|         public override async Task<Empty> DeleteFile(DeleteFileRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var file = await fileService.GetFileAsync(request.Id); | ||||
|             if (file == null) | ||||
|             { | ||||
|                 throw new RpcException(new Status(StatusCode.NotFound, "File not found")); | ||||
|             } | ||||
|  | ||||
|             await fileService.DeleteFileAsync(file); | ||||
|             return new Empty(); | ||||
|         } | ||||
|  | ||||
|         public override async Task<Shared.Proto.CloudFile> ProcessNewFile(IAsyncStreamReader<ProcessNewFileRequest> requestStream, | ||||
|             ServerCallContext context) | ||||
|         { | ||||
|             ProcessNewFileRequest? metadataRequest = null; | ||||
|             var chunks = new List<byte[]>(); | ||||
|  | ||||
|             await foreach (var message in requestStream.ReadAllAsync()) | ||||
|             { | ||||
|                 if (message.DataCase == ProcessNewFileRequest.DataOneofCase.Metadata) | ||||
|                 { | ||||
|                     metadataRequest = message; | ||||
|                 } | ||||
|                 else if (message.DataCase == ProcessNewFileRequest.DataOneofCase.Chunk) | ||||
|                 { | ||||
|                     chunks.Add(message.Chunk.ToByteArray()); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (metadataRequest == null || metadataRequest.Metadata == null) | ||||
|             { | ||||
|                 throw new RpcException(new Status(StatusCode.InvalidArgument, "Missing file metadata")); | ||||
|             } | ||||
|  | ||||
|             var metadata = metadataRequest.Metadata; | ||||
|             using var memoryStream = new MemoryStream(); | ||||
|             foreach (var chunk in chunks) | ||||
|             { | ||||
|                 await memoryStream.WriteAsync(chunk); | ||||
|             } | ||||
|  | ||||
|             memoryStream.Position = 0; | ||||
|  | ||||
|             // Assuming you have an Account object available or can create a dummy one for now | ||||
|             // You might need to adjust this based on how accounts are handled in your system | ||||
|             var dummyAccount = new Account { Id = metadata.AccountId }; | ||||
|  | ||||
|             var cloudFile = await fileService.ProcessNewFileAsync( | ||||
|                 dummyAccount, | ||||
|                 metadata.FileId, | ||||
|                 memoryStream, | ||||
|                 metadata.FileName, | ||||
|                 metadata.ContentType | ||||
|             ); | ||||
|             return cloudFile.ToProtoValue(); | ||||
|         } | ||||
|  | ||||
|         public override async Task<Shared.Proto.CloudFile> UploadFileToRemote( | ||||
|             IAsyncStreamReader<UploadFileToRemoteRequest> requestStream, ServerCallContext context) | ||||
|         { | ||||
|             UploadFileToRemoteRequest? metadataRequest = null; | ||||
|             var chunks = new List<byte[]>(); | ||||
|  | ||||
|             await foreach (var message in requestStream.ReadAllAsync()) | ||||
|             { | ||||
|                 if (message.DataCase == UploadFileToRemoteRequest.DataOneofCase.Metadata) | ||||
|                 { | ||||
|                     metadataRequest = message; | ||||
|                 } | ||||
|                 else if (message.DataCase == UploadFileToRemoteRequest.DataOneofCase.Chunk) | ||||
|                 { | ||||
|                     chunks.Add(message.Chunk.ToByteArray()); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (metadataRequest == null || metadataRequest.Metadata == null) | ||||
|             { | ||||
|                 throw new RpcException(new Status(StatusCode.InvalidArgument, "Missing upload metadata")); | ||||
|             } | ||||
|  | ||||
|             var metadata = metadataRequest.Metadata; | ||||
|             using var memoryStream = new MemoryStream(); | ||||
|             foreach (var chunk in chunks) | ||||
|             { | ||||
|                 await memoryStream.WriteAsync(chunk); | ||||
|             } | ||||
|  | ||||
|             memoryStream.Position = 0; | ||||
|  | ||||
|             var file = await fileService.GetFileAsync(metadata.FileId); | ||||
|             if (file == null) | ||||
|             { | ||||
|                 throw new RpcException(new Status(StatusCode.NotFound, "File not found")); | ||||
|             } | ||||
|  | ||||
|             var uploadedFile = await fileService.UploadFileToRemoteAsync( | ||||
|                 file, | ||||
|                 memoryStream, | ||||
|                 metadata.TargetRemote, | ||||
|                 metadata.Suffix | ||||
|             ); | ||||
|             return uploadedFile.ToProtoValue(); | ||||
|         } | ||||
|  | ||||
|         public override async Task<Empty> DeleteFileData(DeleteFileDataRequest request, ServerCallContext context) | ||||
|         { | ||||
|             var file = await fileService.GetFileAsync(request.FileId); | ||||
|             if (file == null) | ||||
|             { | ||||
|                 throw new RpcException(new Status(StatusCode.NotFound, "File not found")); | ||||
|             } | ||||
|  | ||||
|             await fileService.DeleteFileDataAsync(file); | ||||
|             return new Empty(); | ||||
|         } | ||||
|  | ||||
|         public override async Task<LoadFromReferenceResponse> LoadFromReference(LoadFromReferenceRequest request, | ||||
|             ServerCallContext context) | ||||
|         { | ||||
|             // Assuming CloudFileReferenceObject is a simple class/struct that holds an ID | ||||
|             // You might need to define this or adjust the LoadFromReference method in FileService | ||||
|             var references = request.ReferenceIds.Select(id => new CloudFileReferenceObject { Id = id }).ToList(); | ||||
|             var files = await fileService.LoadFromReference(references); | ||||
|             var response = new LoadFromReferenceResponse(); | ||||
|             response.Files.AddRange(files.Where(f => f != null).Select(f => f!.ToProtoValue())); | ||||
|             return response; | ||||
|         } | ||||
|  | ||||
|         public override async Task<IsReferencedResponse> IsReferenced(IsReferencedRequest request, | ||||
|             ServerCallContext context) | ||||
|         { | ||||
|             var isReferenced = await fileService.IsReferencedAsync(request.FileId); | ||||
|             return new IsReferencedResponse { IsReferenced = isReferenced }; | ||||
|         } | ||||
|  | ||||
|         public override async Task<Empty> PurgeCache(PurgeCacheRequest request, ServerCallContext context) | ||||
|         { | ||||
|             await fileService._PurgeCacheAsync(request.FileId); | ||||
|             return new Empty(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user