Initial SDK structure #1
7 changed files with 76 additions and 46 deletions
|
@ -14,6 +14,6 @@ public interface IFrostFSClient
|
||||||
Task<GetResponse> GetContainerAsync(ContainerID containerId);
|
Task<GetResponse> GetContainerAsync(ContainerID containerId);
|
||||||
Task<DeleteResponse> DeleteContainerAsync(ContainerID containerId);
|
Task<DeleteResponse> DeleteContainerAsync(ContainerID containerId);
|
||||||
Task<HeadResponse> GetObjectHeadAsync(ContainerID containerId, ObjectID objectId);
|
Task<HeadResponse> GetObjectHeadAsync(ContainerID containerId, ObjectID objectId);
|
||||||
Task<Object.PutResponse> PutObjectAsync(ContainerID containerId, Stream data);
|
Task<Object.PutResponse> PutObjectAsync(Object.Header header, Stream payload);
|
||||||
Task<Object.DeleteResponse> DeleteObjectAsync(ContainerID containerId, ObjectID objectId);
|
Task<Object.DeleteResponse> DeleteObjectAsync(ContainerID containerId, ObjectID objectId);
|
||||||
}
|
}
|
|
@ -5,14 +5,34 @@ namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
public static class ObjectHeadMapper
|
public static class ObjectHeadMapper
|
||||||
{
|
{
|
||||||
public static ObjectHead ToModel(this Header head)
|
public static Header ToGrpcMessage(this ObjectHeader header)
|
||||||
{
|
{
|
||||||
// var obtype = Enum.Parse<ObjectType>(head.ObjectType.ToString());
|
var objTypeName = Enum.GetName(typeof(ObjectType), header.ObjectType);
|
||||||
return new ObjectHead
|
if (objTypeName is null)
|
||||||
{
|
{
|
||||||
ContainerId = ContainerId.FromHash(head.ContainerId.Value.ToByteArray()),
|
throw new ArgumentException($"Unknown ObjectType. Value: '{header.ObjectType}'.");
|
||||||
Size = (long)head.PayloadLength,
|
}
|
||||||
Version = head.Version.ToModel()
|
return new Header
|
||||||
|
{
|
||||||
|
ContainerId = header.ContainerId.ToGrpcMessage(),
|
||||||
|
ObjectType = Enum.Parse<ObjectType>(objTypeName)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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<ModelsV2.Enums.ObjectType>(objTypeName)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Size = (long)header.PayloadLength,
|
||||||
|
Version = header.Version.ToModel()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,15 +29,16 @@ public partial class Client
|
||||||
return await _objectServiceClient.HeadAsync(request);
|
return await _objectServiceClient.HeadAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PutResponse> PutObjectAsync(ContainerID cid, Stream data)
|
// public async Task<GetResponse> GetObjectAsync(ContainerID cid, ObjectID oid)
|
||||||
|
// {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
public async Task<PutResponse> PutObjectAsync(Header header, Stream payload)
|
||||||
{
|
{
|
||||||
var sessionToken = await CreateSessionAsync(uint.MaxValue);
|
var sessionToken = await CreateSessionAsync(uint.MaxValue);
|
||||||
var header = new Header
|
header.OwnerId = _owner.ToGrpcMessage();
|
||||||
{
|
header.Version = Version.ToGrpcMessage();
|
||||||
ContainerId = cid,
|
|
||||||
OwnerId = _owner.ToGrpcMessage(),
|
|
||||||
Version = Version.ToGrpcMessage()
|
|
||||||
};
|
|
||||||
var oid = new ObjectID
|
var oid = new ObjectID
|
||||||
{
|
{
|
||||||
Value = header.Sha256()
|
Value = header.Sha256()
|
||||||
|
@ -48,17 +49,23 @@ public partial class Client
|
||||||
{
|
{
|
||||||
Init = new PutRequest.Types.Body.Types.Init
|
Init = new PutRequest.Types.Body.Types.Init
|
||||||
{
|
{
|
||||||
Header = header,
|
Header = header
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
request.AddMetaHeader();
|
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);
|
request.Sign(_key);
|
||||||
|
|
||||||
using var stream = await InitObject(request);
|
using var stream = await InitObject(request);
|
||||||
var buffer = new byte[Constants.ObjectChunkSize];
|
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)
|
while (bufferLength > 0)
|
||||||
{
|
{
|
||||||
request.Body = new PutRequest.Types.Body
|
request.Body = new PutRequest.Types.Body
|
||||||
|
@ -68,8 +75,9 @@ public partial class Client
|
||||||
request.VerifyHeader = null;
|
request.VerifyHeader = null;
|
||||||
request.Sign(_key);
|
request.Sign(_key);
|
||||||
await stream.Write(request);
|
await stream.Write(request);
|
||||||
bufferLength = data.Read(buffer, 0, Constants.ObjectChunkSize);
|
bufferLength = payload.Read(buffer, 0, Constants.ObjectChunkSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await stream.Close();
|
return await stream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +87,7 @@ public partial class Client
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(initRequest));
|
throw new ArgumentNullException(nameof(initRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
var call = _objectServiceClient.Put();
|
var call = _objectServiceClient.Put();
|
||||||
await call.RequestStream.WriteAsync(initRequest);
|
await call.RequestStream.WriteAsync(initRequest);
|
||||||
return new ObjectStreamer { Call = call };
|
return new ObjectStreamer { Call = call };
|
||||||
|
|
|
@ -8,7 +8,7 @@ public class Container
|
||||||
public Guid Nonce { get; set; }
|
public Guid Nonce { get; set; }
|
||||||
public BasicACL BasicAcl { get; set; }
|
public BasicACL BasicAcl { get; set; }
|
||||||
public PlacementPolicy PlacementPolicy { get; set; }
|
public PlacementPolicy PlacementPolicy { get; set; }
|
||||||
public Version? Version { get; set; }
|
public Version Version { get; set; }
|
||||||
|
|
||||||
public Container(BasicACL basicAcl, PlacementPolicy placementPolicy)
|
public Container(BasicACL basicAcl, PlacementPolicy placementPolicy)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace FrostFS.SDK.ModelsV2.Enums;
|
||||||
|
|
||||||
public enum ObjectType
|
public enum ObjectType
|
||||||
{
|
{
|
||||||
Regular = 1,
|
Regular = 0,
|
||||||
Tombstone = 2,
|
Tombstone = 1,
|
||||||
Lock = 3
|
Lock = 3
|
||||||
}
|
}
|
|
@ -1,28 +1,23 @@
|
||||||
|
using FrostFS.SDK.ModelsV2.Enums;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ModelsV2;
|
||||||
|
|
||||||
public class ObjectHead
|
public class ObjectHeader
|
||||||
{
|
{
|
||||||
public ContainerId ContainerId { get; set; }
|
public ContainerId ContainerId { get; set; }
|
||||||
public long Size { 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 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -43,7 +43,7 @@ public class FrostFsService
|
||||||
var deleteContainerResponse = await _client.DeleteContainerAsync(containerId.ToGrpcMessage());
|
var deleteContainerResponse = await _client.DeleteContainerAsync(containerId.ToGrpcMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ObjectHead> GetObjectHeadAsync(ContainerId containerId, ObjectId objectId)
|
public async Task<ObjectHeader> GetObjectHeadAsync(ContainerId containerId, ObjectId objectId)
|
||||||
{
|
{
|
||||||
var getObjectHeadResponse = await _client.GetObjectHeadAsync(
|
var getObjectHeadResponse = await _client.GetObjectHeadAsync(
|
||||||
containerId.ToGrpcMessage(),
|
containerId.ToGrpcMessage(),
|
||||||
|
@ -52,9 +52,15 @@ public class FrostFsService
|
||||||
return getObjectHeadResponse.Body.Header.Header.ToModel();
|
return getObjectHeadResponse.Body.Header.Header.ToModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ObjectId> PutObjectAsync(ModelsV2.Object obj)
|
public async Task<ObjectId> 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<ObjectId> PutObjectAsync(ObjectHeader header, byte[] payload)
|
||||||
|
{
|
||||||
|
var putObjectResponse = await _client.PutObjectAsync(header.ToGrpcMessage(), new MemoryStream(payload));
|
||||||
return ObjectId.FromHash(putObjectResponse.Body.ObjectId.Value.ToByteArray());
|
return ObjectId.FromHash(putObjectResponse.Body.ObjectId.Value.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue