Initial SDK structure #1

Merged
i.pchelintsev merged 18 commits from i.pchelintsev/frostfs-sdk-csharp:master into master 2024-09-04 19:51:24 +00:00
20 changed files with 61 additions and 40 deletions
Showing only changes of commit 0d83541d82 - Show all commits

View file

@ -8,6 +8,7 @@ using FrostFS.SDK.ModelsV2;
using FrostFS.Session; using FrostFS.Session;
using Grpc.Core; using Grpc.Core;
using Grpc.Net.Client; using Grpc.Net.Client;
using Version = FrostFS.SDK.ModelsV2.Version;
namespace FrostFS.SDK.ClientV2; namespace FrostFS.SDK.ClientV2;
@ -16,7 +17,7 @@ public partial class Client: IFrostFSClient
private GrpcChannel _channel; private GrpcChannel _channel;
private readonly ECDsa _key; private readonly ECDsa _key;
private readonly OwnerId _owner; private readonly OwnerId _owner;
public readonly ModelsV2.Version Version = new (2, 13); public readonly Version Version = new (2, 13);
private ContainerService.ContainerServiceClient _containerServiceClient; private ContainerService.ContainerServiceClient _containerServiceClient;
private NetmapService.NetmapServiceClient _netmapServiceClient; private NetmapService.NetmapServiceClient _netmapServiceClient;

View file

@ -1,14 +1,18 @@
using FrostFS.Container;
using FrostFS.Object; using FrostFS.Object;
using FrostFS.Refs; using FrostFS.Refs;
using DeleteResponse = FrostFS.Container.DeleteResponse;
using GetResponse = FrostFS.Container.GetResponse;
using PutResponse = FrostFS.Container.PutResponse;
namespace FrostFS.SDK.ClientV2; namespace FrostFS.SDK.ClientV2;
public interface IFrostFSClient public interface IFrostFSClient
{ {
Task<Container.ListResponse> ListContainersAsync(); Task<ListResponse> ListContainersAsync();
Task<Container.PutResponse> CreateContainerAsync(Container.Container container); Task<PutResponse> CreateContainerAsync(Container.Container container);
Task<Container.GetResponse> GetContainerAsync(ContainerID containerId); Task<GetResponse> GetContainerAsync(ContainerID containerId);
Task<Container.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(ContainerID containerId, Stream data);
Task<Object.DeleteResponse> DeleteObjectAsync(ContainerID containerId, ObjectID objectId); Task<Object.DeleteResponse> DeleteObjectAsync(ContainerID containerId, ObjectID objectId);

View file

@ -1,6 +1,6 @@
using System.Runtime.InteropServices.ComTypes;
using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap; using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
using FrostFS.SDK.Cryptography; using FrostFS.SDK.Cryptography;
using FrostFS.SDK.ModelsV2.Enums;
using Google.Protobuf; using Google.Protobuf;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC; namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
@ -19,14 +19,14 @@ public static class ContainerMapper
public static ModelsV2.Container ToModel(this Container.Container container) public static ModelsV2.Container ToModel(this Container.Container container)
{ {
var basicAclName = Enum.GetName(typeof(ModelsV2.Enums.BasicACL), container.BasicAcl); var basicAclName = Enum.GetName(typeof(BasicACL), container.BasicAcl);
if (basicAclName is null) if (basicAclName is null)
{ {
throw new ArgumentException($"Unknown BasicACL rule. Value: '{container.BasicAcl}'."); throw new ArgumentException($"Unknown BasicACL rule. Value: '{container.BasicAcl}'.");
} }
return new ModelsV2.Container( return new ModelsV2.Container(
Enum.Parse<ModelsV2.Enums.BasicACL>(basicAclName), Enum.Parse<BasicACL>(basicAclName),
container.PlacementPolicy.ToModel() container.PlacementPolicy.ToModel()
) )
{ {

View file

@ -1,5 +1,5 @@
using FrostFS.SDK.ModelsV2;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.SDK.ModelsV2;
using Google.Protobuf; using Google.Protobuf;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC; namespace FrostFS.SDK.ClientV2.Mappers.GRPC;

View file

@ -1,5 +1,6 @@
using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2;
using FrostFS.Session; using FrostFS.Session;
using Version = FrostFS.Refs.Version;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC; namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
@ -9,7 +10,7 @@ public static class MetaHeaderMapper
{ {
return new RequestMetaHeader return new RequestMetaHeader
{ {
Version = new Refs.Version Version = new Version
{ {
Major = (uint)metaHeader.Version.Major, Major = (uint)metaHeader.Version.Major,
Minor = (uint)metaHeader.Version.Minor, Minor = (uint)metaHeader.Version.Minor,

View file

@ -1,4 +1,5 @@
using FrostFS.Netmap; using FrostFS.Netmap;
using Replica = FrostFS.SDK.ModelsV2.Netmap.Replica;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap; namespace FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
@ -23,7 +24,7 @@ public static class PlacementPolicyMapper
public static ModelsV2.Netmap.PlacementPolicy ToModel(this PlacementPolicy placementPolicy) public static ModelsV2.Netmap.PlacementPolicy ToModel(this PlacementPolicy placementPolicy)
{ {
var replicas = new List<ModelsV2.Netmap.Replica>(); var replicas = new List<Replica>();
foreach (var replica in placementPolicy.Replicas) foreach (var replica in placementPolicy.Replicas)
{ {
replicas.Add(replica.ToModel()); replicas.Add(replica.ToModel());

View file

@ -1,11 +1,11 @@
using FrostFS.Object;
using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2;
using FrostFS.SDK.ModelsV2.Enums;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC; namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
public static class ObjectHeadMapper public static class ObjectHeadMapper
{ {
public static ObjectHead ToModel(this Object.Header head) public static ObjectHead ToModel(this Header head)
{ {
// var obtype = Enum.Parse<ObjectType>(head.ObjectType.ToString()); // var obtype = Enum.Parse<ObjectType>(head.ObjectType.ToString());
return new ObjectHead return new ObjectHead

View file

@ -1,5 +1,5 @@
using FrostFS.SDK.ModelsV2;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.SDK.ModelsV2;
using Google.Protobuf; using Google.Protobuf;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC; namespace FrostFS.SDK.ClientV2.Mappers.GRPC;

View file

@ -1,5 +1,5 @@
using FrostFS.SDK.ModelsV2;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.SDK.ModelsV2;
using Google.Protobuf; using Google.Protobuf;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC; namespace FrostFS.SDK.ClientV2.Mappers.GRPC;

View file

@ -1,17 +1,19 @@
using Version = FrostFS.Refs.Version;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC; namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
public static class VersionMapper public static class VersionMapper
{ {
public static Refs.Version ToGrpcMessage(this ModelsV2.Version version) public static Version ToGrpcMessage(this ModelsV2.Version version)
{ {
return new Refs.Version return new Version
{ {
Major = (uint)version.Major, Major = (uint)version.Major,
Minor = (uint)version.Minor Minor = (uint)version.Minor
}; };
} }
public static ModelsV2.Version ToModel(this Refs.Version version) public static ModelsV2.Version ToModel(this Version version)
{ {
return new ModelsV2.Version((int)version.Major, (int)version.Minor); return new ModelsV2.Version((int)version.Major, (int)version.Minor);
} }

View file

@ -1,7 +1,7 @@
using System.Security.Cryptography; using System.Security.Cryptography;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.Session;
using FrostFS.SDK.Cryptography; using FrostFS.SDK.Cryptography;
using FrostFS.Session;
using Google.Protobuf; using Google.Protobuf;
using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Digests;

View file

@ -1,7 +1,7 @@
using System.Security.Cryptography; using System.Security.Cryptography;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.Session;
using FrostFS.SDK.Cryptography; using FrostFS.SDK.Cryptography;
using FrostFS.Session;
using Google.Protobuf; using Google.Protobuf;
using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Digests;

View file

@ -2,6 +2,7 @@ using FrostFS.Object;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.SDK.ClientV2.Mappers.GRPC; using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography; using FrostFS.SDK.Cryptography;
using FrostFS.SDK.ModelsV2;
using FrostFS.Session; using FrostFS.Session;
using Google.Protobuf; using Google.Protobuf;
using Grpc.Core; using Grpc.Core;
@ -56,8 +57,8 @@ public partial class Client
request.Sign(_key); request.Sign(_key);
using var stream = await InitObject(request); using var stream = await InitObject(request);
var buffer = new byte[ModelsV2.Constants.ObjectChunkSize]; var buffer = new byte[Constants.ObjectChunkSize];
var bufferLength = data.Read(buffer, 0, ModelsV2.Constants.ObjectChunkSize); var bufferLength = data.Read(buffer, 0, Constants.ObjectChunkSize);
while (bufferLength > 0) while (bufferLength > 0)
{ {
request.Body = new PutRequest.Types.Body request.Body = new PutRequest.Types.Body
@ -67,7 +68,7 @@ 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, ModelsV2.Constants.ObjectChunkSize); bufferLength = data.Read(buffer, 0, Constants.ObjectChunkSize);
} }
return await stream.Close(); return await stream.Close();
} }

View file

@ -2,7 +2,6 @@
using System.Numerics; using System.Numerics;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using Google.Protobuf;
using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.Sec;
namespace FrostFS.SDK.Cryptography; namespace FrostFS.SDK.Cryptography;

View file

@ -1,3 +1,4 @@
using FrostFS.SDK.ModelsV2.Enums;
using FrostFS.SDK.ModelsV2.Netmap; using FrostFS.SDK.ModelsV2.Netmap;
namespace FrostFS.SDK.ModelsV2; namespace FrostFS.SDK.ModelsV2;
@ -5,11 +6,11 @@ namespace FrostFS.SDK.ModelsV2;
public class Container public class Container
{ {
public Guid Nonce { get; set; } public Guid Nonce { get; set; }
public Enums.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(Enums.BasicACL basicAcl, PlacementPolicy placementPolicy) public Container(BasicACL basicAcl, PlacementPolicy placementPolicy)
{ {
Nonce = Guid.NewGuid(); Nonce = Guid.NewGuid();
BasicAcl = basicAcl; BasicAcl = basicAcl;

View file

@ -5,5 +5,24 @@ public class ObjectHead
{ {
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 Version? Version { get; set; }
}
public class Object : ObjectHead
{
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;
}
} }

View file

@ -1,5 +1,3 @@
using FrostFS.Session;
namespace FrostFS.Session namespace FrostFS.Session
{ {
public interface IRequest : IVerificableMessage public interface IRequest : IVerificableMessage

View file

@ -1,5 +1,5 @@
using Google.Protobuf;
using FrostFS.Session; using FrostFS.Session;
using Google.Protobuf;
namespace FrostFS.Container namespace FrostFS.Container
{ {

View file

@ -1,5 +1,5 @@
using Google.Protobuf; using FrostFS.Session;
using FrostFS.Session; using Google.Protobuf;
namespace FrostFS.Netmap namespace FrostFS.Netmap
{ {

View file

@ -52,15 +52,9 @@ public class FrostFsService
return getObjectHeadResponse.Body.Header.Header.ToModel(); return getObjectHeadResponse.Body.Header.Header.ToModel();
} }
public async Task<ObjectId> PutObjectAsync(ContainerId containerId, Stream data) public async Task<ObjectId> PutObjectAsync(ModelsV2.Object obj)
{ {
var putObjectResponse = await _client.PutObjectAsync(containerId.ToGrpcMessage(), data); var putObjectResponse = await _client.PutObjectAsync(obj.ContainerId.ToGrpcMessage(), obj.Payload);
return ObjectId.FromHash(putObjectResponse.Body.ObjectId.Value.ToByteArray());
}
public async Task<ObjectId> PutObjectAsync(ContainerId containerId, byte[] data)
{
var putObjectResponse = await _client.PutObjectAsync(containerId.ToGrpcMessage(), new MemoryStream(data));
return ObjectId.FromHash(putObjectResponse.Body.ObjectId.Value.ToByteArray()); return ObjectId.FromHash(putObjectResponse.Body.ObjectId.Value.ToByteArray());
} }