From 6b8f8cbd4c163bea7fc8ed991ad4b7fd8756a83d Mon Sep 17 00:00:00 2001 From: Ivan Pchelintsev Date: Thu, 16 May 2024 12:26:32 +0300 Subject: [PATCH] [#1] Add object mappers Signed-off-by: Ivan Pchelintsev --- .../Interfaces/IFrostFSClient.cs | 2 +- .../Mappers/GRPC/Object.cs | 36 ++++++++++++++---- src/FrostFS.SDK.ClientV2/Services/Object.cs | 37 ++++++++++++------- src/FrostFS.SDK.ModelsV2/Container.cs | 2 +- src/FrostFS.SDK.ModelsV2/Enums/ObjectType.cs | 4 +- src/FrostFS.SDK.ModelsV2/Object.cs | 29 ++++++--------- src/FrostFS.SDK.Service/Service.cs | 12 ++++-- 7 files changed, 76 insertions(+), 46 deletions(-) diff --git a/src/FrostFS.SDK.ClientV2/Interfaces/IFrostFSClient.cs b/src/FrostFS.SDK.ClientV2/Interfaces/IFrostFSClient.cs index 0d659ae..fbf897d 100644 --- a/src/FrostFS.SDK.ClientV2/Interfaces/IFrostFSClient.cs +++ b/src/FrostFS.SDK.ClientV2/Interfaces/IFrostFSClient.cs @@ -14,6 +14,6 @@ public interface IFrostFSClient Task GetContainerAsync(ContainerID containerId); Task DeleteContainerAsync(ContainerID containerId); Task GetObjectHeadAsync(ContainerID containerId, ObjectID objectId); - Task PutObjectAsync(ContainerID containerId, Stream data); + Task PutObjectAsync(Object.Header header, Stream payload); Task DeleteObjectAsync(ContainerID containerId, ObjectID objectId); } \ No newline at end of file diff --git a/src/FrostFS.SDK.ClientV2/Mappers/GRPC/Object.cs b/src/FrostFS.SDK.ClientV2/Mappers/GRPC/Object.cs index a457891..8259a61 100644 --- a/src/FrostFS.SDK.ClientV2/Mappers/GRPC/Object.cs +++ b/src/FrostFS.SDK.ClientV2/Mappers/GRPC/Object.cs @@ -4,15 +4,35 @@ using FrostFS.SDK.ModelsV2; namespace FrostFS.SDK.ClientV2.Mappers.GRPC; public static class ObjectHeadMapper -{ - public static ObjectHead ToModel(this Header head) +{ + public static Header ToGrpcMessage(this ObjectHeader header) { - // var obtype = Enum.Parse(head.ObjectType.ToString()); - return new ObjectHead + var objTypeName = Enum.GetName(typeof(ObjectType), header.ObjectType); + if (objTypeName is null) { - ContainerId = ContainerId.FromHash(head.ContainerId.Value.ToByteArray()), - Size = (long)head.PayloadLength, - Version = head.Version.ToModel() + throw new ArgumentException($"Unknown ObjectType. Value: '{header.ObjectType}'."); + } + return new Header + { + ContainerId = header.ContainerId.ToGrpcMessage(), + ObjectType = Enum.Parse(objTypeName) }; } -} \ No newline at end of file + + public static ObjectHeader ToModel(this Header header) + { + var objTypeName = Enum.GetName(typeof(ModelsV2.Enums.ObjectType), header.ObjectType); + if (objTypeName is null) + { + throw new ArgumentException($"Unknown ObjectType. Value: '{header.ObjectType}'."); + } + return new ObjectHeader( + ContainerId.FromHash(header.ContainerId.Value.ToByteArray()), + Enum.Parse(objTypeName) + ) + { + Size = (long)header.PayloadLength, + Version = header.Version.ToModel() + }; + } +} diff --git a/src/FrostFS.SDK.ClientV2/Services/Object.cs b/src/FrostFS.SDK.ClientV2/Services/Object.cs index 1a4b548..74dfc99 100644 --- a/src/FrostFS.SDK.ClientV2/Services/Object.cs +++ b/src/FrostFS.SDK.ClientV2/Services/Object.cs @@ -29,15 +29,16 @@ public partial class Client return await _objectServiceClient.HeadAsync(request); } - public async Task PutObjectAsync(ContainerID cid, Stream data) + // public async Task GetObjectAsync(ContainerID cid, ObjectID oid) + // { + // + // } + + public async Task PutObjectAsync(Header header, Stream payload) { var sessionToken = await CreateSessionAsync(uint.MaxValue); - var header = new Header - { - ContainerId = cid, - OwnerId = _owner.ToGrpcMessage(), - Version = Version.ToGrpcMessage() - }; + header.OwnerId = _owner.ToGrpcMessage(); + header.Version = Version.ToGrpcMessage(); var oid = new ObjectID { Value = header.Sha256() @@ -48,17 +49,23 @@ public partial class Client { Init = new PutRequest.Types.Body.Types.Init { - Header = header, + Header = header }, } }; request.AddMetaHeader(); - request.AddObjectSessionToken(sessionToken, cid, oid, ObjectSessionContext.Types.Verb.Put, _key); + request.AddObjectSessionToken( + sessionToken, + header.ContainerId, + oid, + ObjectSessionContext.Types.Verb.Put, + _key + ); request.Sign(_key); using var stream = await InitObject(request); var buffer = new byte[Constants.ObjectChunkSize]; - var bufferLength = data.Read(buffer, 0, Constants.ObjectChunkSize); + var bufferLength = payload.Read(buffer, 0, Constants.ObjectChunkSize); while (bufferLength > 0) { request.Body = new PutRequest.Types.Body @@ -68,22 +75,24 @@ public partial class Client request.VerifyHeader = null; request.Sign(_key); await stream.Write(request); - bufferLength = data.Read(buffer, 0, Constants.ObjectChunkSize); + bufferLength = payload.Read(buffer, 0, Constants.ObjectChunkSize); } + return await stream.Close(); } - + private async Task InitObject(PutRequest initRequest) { if (initRequest is null) { throw new ArgumentNullException(nameof(initRequest)); } + var call = _objectServiceClient.Put(); await call.RequestStream.WriteAsync(initRequest); return new ObjectStreamer { Call = call }; } - + public async Task DeleteObjectAsync(ContainerID cid, ObjectID oid) { var request = new DeleteRequest @@ -118,7 +127,7 @@ internal class ObjectStreamer : IDisposable { throw new ArgumentNullException(nameof(request)); } - + await Call.RequestStream.WriteAsync(request); } diff --git a/src/FrostFS.SDK.ModelsV2/Container.cs b/src/FrostFS.SDK.ModelsV2/Container.cs index d205bf6..9588483 100644 --- a/src/FrostFS.SDK.ModelsV2/Container.cs +++ b/src/FrostFS.SDK.ModelsV2/Container.cs @@ -8,7 +8,7 @@ public class Container public Guid Nonce { get; set; } public BasicACL BasicAcl { get; set; } public PlacementPolicy PlacementPolicy { get; set; } - public Version? Version { get; set; } + public Version Version { get; set; } public Container(BasicACL basicAcl, PlacementPolicy placementPolicy) { diff --git a/src/FrostFS.SDK.ModelsV2/Enums/ObjectType.cs b/src/FrostFS.SDK.ModelsV2/Enums/ObjectType.cs index 5d206a0..6f8a905 100644 --- a/src/FrostFS.SDK.ModelsV2/Enums/ObjectType.cs +++ b/src/FrostFS.SDK.ModelsV2/Enums/ObjectType.cs @@ -2,7 +2,7 @@ namespace FrostFS.SDK.ModelsV2.Enums; public enum ObjectType { - Regular = 1, - Tombstone = 2, + Regular = 0, + Tombstone = 1, Lock = 3 } \ No newline at end of file diff --git a/src/FrostFS.SDK.ModelsV2/Object.cs b/src/FrostFS.SDK.ModelsV2/Object.cs index b588eab..a38a052 100644 --- a/src/FrostFS.SDK.ModelsV2/Object.cs +++ b/src/FrostFS.SDK.ModelsV2/Object.cs @@ -1,28 +1,23 @@ +using FrostFS.SDK.ModelsV2.Enums; namespace FrostFS.SDK.ModelsV2; -public class ObjectHead +public class ObjectHeader { public ContainerId ContainerId { get; set; } public long Size { get; set; } - public Version? Version { get; set; } + public ObjectType ObjectType { get; set; } + public Version Version { get; set; } + + public ObjectHeader(ContainerId containerId, ObjectType type = ObjectType.Regular) + { + ContainerId = containerId; + ObjectType = type; + } } -public class Object : ObjectHead +public class Object { + public ObjectHeader Header { get; set; } public Stream Payload { get; set; } - - public Object(ContainerId containerId, Stream payload) - { - ContainerId = containerId; - Payload = payload; - Size = Payload.Length; - } - - public Object(ContainerId containerId, byte[] payload) - { - ContainerId = containerId; - Payload = new MemoryStream(payload); - Size = Payload.Length; - } } \ No newline at end of file diff --git a/src/FrostFS.SDK.Service/Service.cs b/src/FrostFS.SDK.Service/Service.cs index 0cd0ad4..b528424 100644 --- a/src/FrostFS.SDK.Service/Service.cs +++ b/src/FrostFS.SDK.Service/Service.cs @@ -43,7 +43,7 @@ public class FrostFsService var deleteContainerResponse = await _client.DeleteContainerAsync(containerId.ToGrpcMessage()); } - public async Task GetObjectHeadAsync(ContainerId containerId, ObjectId objectId) + public async Task GetObjectHeadAsync(ContainerId containerId, ObjectId objectId) { var getObjectHeadResponse = await _client.GetObjectHeadAsync( containerId.ToGrpcMessage(), @@ -52,9 +52,15 @@ public class FrostFsService return getObjectHeadResponse.Body.Header.Header.ToModel(); } - public async Task PutObjectAsync(ModelsV2.Object obj) + public async Task PutObjectAsync(ObjectHeader header, Stream payload) { - var putObjectResponse = await _client.PutObjectAsync(obj.ContainerId.ToGrpcMessage(), obj.Payload); + var putObjectResponse = await _client.PutObjectAsync(header.ToGrpcMessage(), payload); + return ObjectId.FromHash(putObjectResponse.Body.ObjectId.Value.ToByteArray()); + } + + public async Task PutObjectAsync(ObjectHeader header, byte[] payload) + { + var putObjectResponse = await _client.PutObjectAsync(header.ToGrpcMessage(), new MemoryStream(payload)); return ObjectId.FromHash(putObjectResponse.Body.ObjectId.Value.ToByteArray()); }