[#23] Client: Refactoring to optimize memory usage
All checks were successful
DCO / DCO (pull_request) Successful in 33s
All checks were successful
DCO / DCO (pull_request) Successful in 33s
Signed-off-by: Pavel Gross <p.gross@yando.com>
This commit is contained in:
parent
1a02ac2ae7
commit
6562aa27a5
141 changed files with 1722 additions and 896 deletions
|
@ -1,16 +1,13 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
#
|
|
||||||
VisualStudioVersion = 17.5.002.0
|
VisualStudioVersion = 17.5.002.0
|
||||||
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.ClientV2", "src\FrostFS.SDK.ClientV2\FrostFS.SDK.ClientV2.csproj", "{50D8F61F-C302-4AC9-8D8A-AB0B8C0988C3}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.ClientV2", "src\FrostFS.SDK.ClientV2\FrostFS.SDK.ClientV2.csproj", "{50D8F61F-C302-4AC9-8D8A-AB0B8C0988C3}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.Cryptography", "src\FrostFS.SDK.Cryptography\FrostFS.SDK.Cryptography.csproj", "{3D804F4A-B0B2-47A5-B006-BE447BE64B50}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.Cryptography", "src\FrostFS.SDK.Cryptography\FrostFS.SDK.Cryptography.csproj", "{3D804F4A-B0B2-47A5-B006-BE447BE64B50}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.ModelsV2", "src\FrostFS.SDK.ModelsV2\FrostFS.SDK.ModelsV2.csproj", "{14DC8AC7-E310-40C2-ACDF-5BE78FC0E1B2}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.ProtosV2", "src\FrostFS.SDK.ProtosV2\FrostFS.SDK.ProtosV2.csproj", "{5012EF96-9C9E-4E77-BC78-B4111EE54107}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.ProtosV2", "src\FrostFS.SDK.ProtosV2\FrostFS.SDK.ProtosV2.csproj", "{5012EF96-9C9E-4E77-BC78-B4111EE54107}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FrostFS.SDK.Tests", "src\FrostFS.SDK.Tests\FrostFS.SDK.Tests.csproj", "{8FDA7E0D-9C75-4874-988E-6592CD28F76C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.Tests", "src\FrostFS.SDK.Tests\FrostFS.SDK.Tests.csproj", "{8FDA7E0D-9C75-4874-988E-6592CD28F76C}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -26,10 +23,6 @@ Global
|
||||||
{3D804F4A-B0B2-47A5-B006-BE447BE64B50}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{3D804F4A-B0B2-47A5-B006-BE447BE64B50}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{3D804F4A-B0B2-47A5-B006-BE447BE64B50}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{3D804F4A-B0B2-47A5-B006-BE447BE64B50}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{3D804F4A-B0B2-47A5-B006-BE447BE64B50}.Release|Any CPU.Build.0 = Release|Any CPU
|
{3D804F4A-B0B2-47A5-B006-BE447BE64B50}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{14DC8AC7-E310-40C2-ACDF-5BE78FC0E1B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{14DC8AC7-E310-40C2-ACDF-5BE78FC0E1B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{14DC8AC7-E310-40C2-ACDF-5BE78FC0E1B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{14DC8AC7-E310-40C2-ACDF-5BE78FC0E1B2}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{5012EF96-9C9E-4E77-BC78-B4111EE54107}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{5012EF96-9C9E-4E77-BC78-B4111EE54107}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{5012EF96-9C9E-4E77-BC78-B4111EE54107}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{5012EF96-9C9E-4E77-BC78-B4111EE54107}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{5012EF96-9C9E-4E77-BC78-B4111EE54107}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{5012EF96-9C9E-4E77-BC78-B4111EE54107}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
|
173
README.md
173
README.md
|
@ -21,137 +21,62 @@ neo-go wallet export -w <path_to_your_wallet> -d <address_from_p1>
|
||||||
### Container
|
### Container
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
using FrostFS.SDK;
|
||||||
using FrostFS.SDK.ClientV2;
|
using FrostFS.SDK.ClientV2;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using FrostFS.SDK.ModelsV2.Enums;
|
|
||||||
using FrostFS.SDK.ModelsV2.Netmap;
|
|
||||||
|
|
||||||
var fsClient = Client.GetInstance(<your_key>, <your_host>);
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
// List containers
|
var Key = "KwHDAJ66o8FoLBjVbjP2sWBmgBMGjt7Vv4boA7xQrBoAYBE397Aq";
|
||||||
var containersIds = await fsClient.ListContainersAsync();
|
var Host = "http://172.22.33.44:8080";
|
||||||
|
|
||||||
// Create container
|
var options = Options.Create(new SingleOwnerClientSettings
|
||||||
var placementPolicy = new PlacementPolicy(true, new Replica(1));
|
|
||||||
var containerId = await fsClient.CreateContainerAsync(
|
|
||||||
new Container(
|
|
||||||
BasicAcl.PublicRW,
|
|
||||||
placementPolicy
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get container
|
|
||||||
var container = await fsClient.GetContainerAsync(cId);
|
|
||||||
|
|
||||||
// Delete container
|
|
||||||
await fsClient.DeleteContainerAsync(containerId);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Object
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using FrostFS.SDK.ClientV2;
|
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using FrostFS.SDK.ModelsV2.Enums;
|
|
||||||
using FrostFS.SDK.ModelsV2.Netmap;
|
|
||||||
|
|
||||||
var fsClient = Client.GetInstance(<your_key>, <your_host>);
|
|
||||||
|
|
||||||
// Search regular objects
|
|
||||||
var objectsIds = await fsClient.SearchObjectAsync(
|
|
||||||
cId,
|
|
||||||
ObjectFilter.RootFilter()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Put object
|
|
||||||
var f = File.OpenRead("cat.jpg");
|
|
||||||
var cat = new ObjectHeader(
|
|
||||||
containerId: cId,
|
|
||||||
type: ObjectType.Regular,
|
|
||||||
new ObjectAttribute("Filename", "cat.jpg")
|
|
||||||
);
|
|
||||||
var oId = await fsClient.PutObjectAsync(cat, f);
|
|
||||||
|
|
||||||
// Get object header
|
|
||||||
var objHeader = await fsClient.GetObjectHeadAsync(cId, oId);
|
|
||||||
|
|
||||||
// Get object
|
|
||||||
var obj = await fsClient.GetObjectAsync(cId, oId);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom client cut
|
|
||||||
```csharp
|
|
||||||
|
|
||||||
using FrostFS.SDK.ClientV2;
|
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using FrostFS.SDK.ModelsV2.Enums;
|
|
||||||
using FrostFS.SDK.ModelsV2.Netmap;
|
|
||||||
using FrostFS.SDK.ClientV2.Extensions;
|
|
||||||
using FrostFS.SDK.ClientV2.Interfaces;
|
|
||||||
|
|
||||||
var fsClient = Client.GetInstance(<your_key>, <your_host>);
|
|
||||||
|
|
||||||
ContainerId containerId = <containerId>;
|
|
||||||
string fileName = <fileName>;
|
|
||||||
|
|
||||||
await PutObjectClientCut(fsClient, containerId, fileName);
|
|
||||||
|
|
||||||
static async Task<ObjectId?> PutObjectClientCut(IFrostFSClient fsClient, ContainerId containerId, string fileName)
|
|
||||||
{
|
{
|
||||||
List<ObjectId> sentObjectIds = [];
|
Key = Key,
|
||||||
FrostFS.SDK.ModelsV2.Object? currentObject;
|
Host = Host
|
||||||
|
});
|
||||||
|
|
||||||
var partSize = 1024 * 1024;
|
using var client = Client.GetSingleOwnerInstance(options);
|
||||||
var buffer = new byte[partSize];
|
|
||||||
|
|
||||||
var largeObject = new LargeObject(containerId);
|
await foreach (var cid in client.ListContainersAsync())
|
||||||
|
{
|
||||||
var split = new Split();
|
await client.DeleteContainerAsync(new PrmContainerDelete(cid));
|
||||||
|
|
||||||
var fileInfo = new FileInfo(fileName);
|
|
||||||
var fullLength = (ulong)fileInfo.Length;
|
|
||||||
var fileNameAttribute = new ObjectAttribute("fileName", fileInfo.Name);
|
|
||||||
|
|
||||||
using var stream = File.OpenRead(fileName);
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
var bytesCount = await stream.ReadAsync(buffer.AsMemory(0, partSize));
|
|
||||||
|
|
||||||
split.Previous = sentObjectIds.LastOrDefault();
|
|
||||||
|
|
||||||
largeObject.AppendBlock(buffer, bytesCount);
|
|
||||||
|
|
||||||
currentObject = new FrostFS.SDK.ModelsV2.Object(containerId, bytesCount < partSize ? buffer.Take(bytesCount).ToArray() : buffer)
|
|
||||||
.AddAttribute(fileNameAttribute)
|
|
||||||
.SetSplit(split);
|
|
||||||
|
|
||||||
if (largeObject.PayloadLength == fullLength)
|
|
||||||
break;
|
|
||||||
|
|
||||||
var objectId = await fsClient.PutSingleObjectAsync(currentObject);
|
|
||||||
sentObjectIds.Add(objectId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sentObjectIds.Any())
|
|
||||||
{
|
|
||||||
largeObject.CalculateHash()
|
|
||||||
.AddAttribute(fileNameAttribute);
|
|
||||||
|
|
||||||
currentObject.SetParent(largeObject);
|
|
||||||
|
|
||||||
var objectId = await fsClient.PutSingleObjectAsync(currentObject);
|
|
||||||
sentObjectIds.Add(objectId);
|
|
||||||
|
|
||||||
var linkObject = new LinkObject(containerId, split.SplitId, largeObject)
|
|
||||||
.AddChildren(sentObjectIds)
|
|
||||||
.AddAttribute(fileNameAttribute);
|
|
||||||
|
|
||||||
_ = await fsClient.PutSingleObjectAsync(linkObject);
|
|
||||||
|
|
||||||
return currentObject.GetParentId();
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fsClient.PutSingleObjectAsync(currentObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var placementPolicy = new FrostFsPlacementPolicy(true, new FrostFsReplica(1));
|
||||||
|
|
||||||
|
var createContainerParam = new PrmContainerCreate(
|
||||||
|
new FrostFsContainerInfo(BasicAcl.PublicRW, new FrostFsPlacementPolicy(true, new FrostFsReplica(1))));
|
||||||
|
|
||||||
|
var containerId = await client.CreateContainerAsync(createContainerParam);
|
||||||
|
|
||||||
|
using var fileStream = File.OpenRead(@"C:\Users\Paul\Pictures\cat.jpeg");
|
||||||
|
|
||||||
|
var param = new PrmObjectPut
|
||||||
|
{
|
||||||
|
Header = new FrostFsObjectHeader(
|
||||||
|
containerId: containerId,
|
||||||
|
type: FrostFsObjectType.Regular,
|
||||||
|
[new FrostFsAttribute("fileName", "test")]),
|
||||||
|
Payload = fileStream
|
||||||
|
};
|
||||||
|
|
||||||
|
FrostFsObjectId objectId = await client.PutObjectAsync(param);
|
||||||
|
|
||||||
|
var filter = new FilterByAttribute(FrostFsObjectMatchType.Equals, "fileName", "test");
|
||||||
|
|
||||||
|
await foreach (var objId in client.SearchObjectsAsync(new PrmObjectSearch(containerId) { Filters = [filter] }))
|
||||||
|
{
|
||||||
|
var objHeader = await client.GetObjectHeadAsync(new PrmObjectHeadGet(containerId, objId));
|
||||||
|
}
|
||||||
|
|
||||||
|
var @object = await client.GetObjectAsync(new PrmObjectGet(containerId, objectId));
|
||||||
|
|
||||||
|
var downloadedBytes = new byte[@object.Header.PayloadLength];
|
||||||
|
MemoryStream ms = new(downloadedBytes);
|
||||||
|
|
||||||
|
ReadOnlyMemory<byte>? chunk = null;
|
||||||
|
while ((chunk = await @object.ObjectReader!.ReadChunk()) != null)
|
||||||
|
{
|
||||||
|
ms.Write(chunk.Value.Span);
|
||||||
|
}
|
||||||
```
|
```
|
|
@ -1,6 +1,4 @@
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2
|
namespace FrostFS.SDK.ClientV2
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
using FrostFS.Container;
|
using System;
|
||||||
using FrostFS.Netmap;
|
|
||||||
using FrostFS.Object;
|
|
||||||
using FrostFS.SDK.ClientV2.Interfaces;
|
|
||||||
using FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
using FrostFS.SDK.Cryptography;
|
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using FrostFS.SDK.ModelsV2.Netmap;
|
|
||||||
using FrostFS.Session;
|
|
||||||
using Grpc.Core;
|
|
||||||
using Grpc.Core.Interceptors;
|
|
||||||
using Grpc.Net.Client;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Version = FrostFS.SDK.ModelsV2.Version;
|
|
||||||
|
using FrostFS.Container;
|
||||||
|
using FrostFS.Netmap;
|
||||||
|
using FrostFS.Object;
|
||||||
|
using FrostFS.SDK.ClientV2.Interfaces;
|
||||||
|
using FrostFS.SDK.ClientV2;
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
using FrostFS.Session;
|
||||||
|
|
||||||
|
using Grpc.Core;
|
||||||
|
using Grpc.Core.Interceptors;
|
||||||
|
using Grpc.Net.Client;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
|
@ -70,14 +70,14 @@ public class Client : IFrostFSClient
|
||||||
ObjectService.ObjectServiceClient objectService)
|
ObjectService.ObjectServiceClient objectService)
|
||||||
{
|
{
|
||||||
var ecdsaKey = settings.Value.Key.LoadWif();
|
var ecdsaKey = settings.Value.Key.LoadWif();
|
||||||
OwnerId.FromKey(ecdsaKey);
|
FrostFsOwner.FromKey(ecdsaKey);
|
||||||
|
|
||||||
ClientCtx = new ClientEnvironment(
|
ClientCtx = new ClientEnvironment(
|
||||||
client: this,
|
client: this,
|
||||||
key: ecdsaKey,
|
key: ecdsaKey,
|
||||||
owner: OwnerId.FromKey(ecdsaKey),
|
owner: FrostFsOwner.FromKey(ecdsaKey),
|
||||||
channel: InitGrpcChannel(settings.Value.Host, channelOptions),
|
channel: InitGrpcChannel(settings.Value.Host, channelOptions),
|
||||||
version: new Version(2, 13));
|
version: new FrostFsVersion(2, 13));
|
||||||
|
|
||||||
ContainerServiceClient = containerService;
|
ContainerServiceClient = containerService;
|
||||||
NetmapServiceClient = netmapService;
|
NetmapServiceClient = netmapService;
|
||||||
|
@ -98,7 +98,7 @@ public class Client : IFrostFSClient
|
||||||
key: null,
|
key: null,
|
||||||
owner: null,
|
owner: null,
|
||||||
channel: channel,
|
channel: channel,
|
||||||
version: new Version(2, 13));
|
version: new FrostFsVersion(2, 13));
|
||||||
|
|
||||||
// TODO: define timeout logic
|
// TODO: define timeout logic
|
||||||
// CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20) });
|
// CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20) });
|
||||||
|
@ -117,9 +117,9 @@ public class Client : IFrostFSClient
|
||||||
ClientCtx = new ClientEnvironment(
|
ClientCtx = new ClientEnvironment(
|
||||||
this,
|
this,
|
||||||
key: ecdsaKey,
|
key: ecdsaKey,
|
||||||
owner: OwnerId.FromKey(ecdsaKey),
|
owner: FrostFsOwner.FromKey(ecdsaKey),
|
||||||
channel: channel,
|
channel: channel,
|
||||||
version: new Version(2, 13));
|
version: new FrostFsVersion(2, 13));
|
||||||
|
|
||||||
// TODO: define timeout logic
|
// TODO: define timeout logic
|
||||||
CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20)});
|
CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20)});
|
||||||
|
@ -135,26 +135,26 @@ public class Client : IFrostFSClient
|
||||||
{
|
{
|
||||||
if (disposing && !isDisposed)
|
if (disposing && !isDisposed)
|
||||||
{
|
{
|
||||||
ClientCtx.Dispose();
|
ClientCtx?.Dispose();
|
||||||
isDisposed = true;
|
isDisposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ContainerImplementation
|
#region ContainerImplementation
|
||||||
public Task<ModelsV2.Container> GetContainerAsync(PrmContainerGet args)
|
public Task<FrostFsContainerInfo> GetContainerAsync(PrmContainerGet args)
|
||||||
{
|
{
|
||||||
var service = GetContainerService(args);
|
var service = GetContainerService(args);
|
||||||
return service.GetContainerAsync(args);
|
return service.GetContainerAsync(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAsyncEnumerable<ContainerId> ListContainersAsync(PrmContainerGetAll? args = null)
|
public IAsyncEnumerable<FrostFsContainerId> ListContainersAsync(PrmContainerGetAll? args = null)
|
||||||
{
|
{
|
||||||
args ??= new PrmContainerGetAll();
|
args ??= new PrmContainerGetAll();
|
||||||
var service = GetContainerService(args);
|
var service = GetContainerService(args);
|
||||||
return service.ListContainersAsync(args);
|
return service.ListContainersAsync(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ContainerId> CreateContainerAsync(PrmContainerCreate args)
|
public Task<FrostFsContainerId> CreateContainerAsync(PrmContainerCreate args)
|
||||||
{
|
{
|
||||||
var service = GetContainerService(args);
|
var service = GetContainerService(args);
|
||||||
return service.CreateContainerAsync(args);
|
return service.CreateContainerAsync(args);
|
||||||
|
@ -168,14 +168,14 @@ public class Client : IFrostFSClient
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region NetworkImplementation
|
#region NetworkImplementation
|
||||||
public Task<NetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot? args)
|
public Task<FrostFsNetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot? args)
|
||||||
{
|
{
|
||||||
args ??= new PrmNetmapSnapshot();
|
args ??= new PrmNetmapSnapshot();
|
||||||
var service = GetNetmapService(args);
|
var service = GetNetmapService(args);
|
||||||
return service.GetNetmapSnapshotAsync(args);
|
return service.GetNetmapSnapshotAsync(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ModelsV2.Netmap.NodeInfo> GetNodeInfoAsync(PrmNodeInfo? args)
|
public Task<FrostFsNodeInfo> GetNodeInfoAsync(PrmNodeInfo? args)
|
||||||
{
|
{
|
||||||
args ??= new PrmNodeInfo();
|
args ??= new PrmNodeInfo();
|
||||||
var service = GetNetmapService(args);
|
var service = GetNetmapService(args);
|
||||||
|
@ -191,7 +191,7 @@ public class Client : IFrostFSClient
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ObjectImplementation
|
#region ObjectImplementation
|
||||||
public Task<ObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args)
|
public Task<FrostFsObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args)
|
||||||
{
|
{
|
||||||
var service = GetObjectService(args);
|
var service = GetObjectService(args);
|
||||||
return service.GetObjectHeadAsync(args);
|
return service.GetObjectHeadAsync(args);
|
||||||
|
@ -203,13 +203,13 @@ public class Client : IFrostFSClient
|
||||||
return service.GetObjectAsync(args);
|
return service.GetObjectAsync(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ObjectId> PutObjectAsync(PrmObjectPut args)
|
public Task<FrostFsObjectId> PutObjectAsync(PrmObjectPut args)
|
||||||
{
|
{
|
||||||
var service = GetObjectService(args);
|
var service = GetObjectService(args);
|
||||||
return service.PutObjectAsync(args);
|
return service.PutObjectAsync(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ObjectId> PutSingleObjectAsync(PrmSingleObjectPut args)
|
public Task<FrostFsObjectId> PutSingleObjectAsync(PrmSingleObjectPut args)
|
||||||
{
|
{
|
||||||
var service = GetObjectService(args);
|
var service = GetObjectService(args);
|
||||||
return service.PutSingleObjectAsync(args);
|
return service.PutSingleObjectAsync(args);
|
||||||
|
@ -221,7 +221,7 @@ public class Client : IFrostFSClient
|
||||||
return service.DeleteObjectAsync(args);
|
return service.DeleteObjectAsync(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAsyncEnumerable<ObjectId> SearchObjectsAsync(PrmObjectSearch args)
|
public IAsyncEnumerable<FrostFsObjectId> SearchObjectsAsync(PrmObjectSearch args)
|
||||||
{
|
{
|
||||||
var service = GetObjectService(args);
|
var service = GetObjectService(args);
|
||||||
return service.SearchObjectsAsync(args);
|
return service.SearchObjectsAsync(args);
|
||||||
|
@ -229,12 +229,12 @@ public class Client : IFrostFSClient
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region SessionImplementation
|
#region SessionImplementation
|
||||||
public async Task<ModelsV2.SessionToken> CreateSessionAsync(PrmSessionCreate args)
|
public async Task<FrostFsSessionToken> CreateSessionAsync(PrmSessionCreate args)
|
||||||
{
|
{
|
||||||
var session = await CreateSessionInternalAsync(args);
|
var session = await CreateSessionInternalAsync(args);
|
||||||
var token = session.Serialize();
|
var token = session.Serialize();
|
||||||
|
|
||||||
return new ModelsV2.SessionToken(token);
|
return new FrostFsSessionToken(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Task<Session.SessionToken> CreateSessionInternalAsync(PrmSessionCreate args)
|
internal Task<Session.SessionToken> CreateSessionInternalAsync(PrmSessionCreate args)
|
||||||
|
@ -245,7 +245,7 @@ public class Client : IFrostFSClient
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ToolsImplementation
|
#region ToolsImplementation
|
||||||
public ObjectId CalculateObjectId(ObjectHeader header, Context ctx)
|
public FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx)
|
||||||
{
|
{
|
||||||
if (header == null)
|
if (header == null)
|
||||||
throw new ArgumentNullException(nameof(header));
|
throw new ArgumentNullException(nameof(header));
|
||||||
|
@ -286,7 +286,7 @@ public class Client : IFrostFSClient
|
||||||
|
|
||||||
if (ctx.Context.OwnerId == null)
|
if (ctx.Context.OwnerId == null)
|
||||||
{
|
{
|
||||||
ctx.Context.OwnerId = ClientCtx.Owner ?? OwnerId.FromKey(ctx.Context.Key);
|
ctx.Context.OwnerId = ClientCtx.Owner ?? FrostFsOwner.FromKey(ctx.Context.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Context.Version == null)
|
if (ctx.Context.Version == null)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using FrostFS.SDK.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2
|
namespace FrostFS.SDK.ClientV2
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
|
public class InvalidObjectException() : Exception()
|
||||||
|
{
|
||||||
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public class ResponseException(ResponseStatus status) : Exception()
|
public class ResponseException(FrostFsResponseStatus status) : Exception()
|
||||||
{
|
{
|
||||||
public ResponseStatus Status { get; set; } = status;
|
public FrostFsResponseStatus Status { get; set; } = status;
|
||||||
}
|
}
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\FrostFS.SDK.Cryptography\FrostFS.SDK.Cryptography.csproj" />
|
<ProjectReference Include="..\FrostFS.SDK.Cryptography\FrostFS.SDK.Cryptography.csproj" />
|
||||||
<ProjectReference Include="..\FrostFS.SDK.ModelsV2\FrostFS.SDK.ModelsV2.csproj" />
|
|
||||||
<ProjectReference Include="..\FrostFS.SDK.ProtosV2\FrostFS.SDK.ProtosV2.csproj" />
|
<ProjectReference Include="..\FrostFS.SDK.ProtosV2\FrostFS.SDK.ProtosV2.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using Grpc.Core.Interceptors;
|
using Grpc.Core.Interceptors;
|
||||||
|
|
||||||
|
|
|
@ -1,50 +1,49 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
using FrostFS.SDK.ModelsV2;
|
using FrostFS.SDK.ClientV2;
|
||||||
using FrostFS.SDK.ModelsV2.Netmap;
|
|
||||||
namespace FrostFS.SDK.ClientV2.Interfaces;
|
namespace FrostFS.SDK.ClientV2.Interfaces;
|
||||||
|
|
||||||
public interface IFrostFSClient : IDisposable
|
public interface IFrostFSClient : IDisposable
|
||||||
{
|
{
|
||||||
#region Network
|
#region Network
|
||||||
Task<NetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot? args = null);
|
Task<FrostFsNetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot? args = null);
|
||||||
|
|
||||||
Task<NodeInfo> GetNodeInfoAsync(PrmNodeInfo? args = null);
|
Task<FrostFsNodeInfo> GetNodeInfoAsync(PrmNodeInfo? args = null);
|
||||||
|
|
||||||
Task<NetworkSettings> GetNetworkSettingsAsync(PrmNetworkSettings? args = null);
|
Task<NetworkSettings> GetNetworkSettingsAsync(PrmNetworkSettings? args = null);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Session
|
#region Session
|
||||||
Task<SessionToken> CreateSessionAsync(PrmSessionCreate args);
|
Task<FrostFsSessionToken> CreateSessionAsync(PrmSessionCreate args);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Container
|
#region Container
|
||||||
Task<ModelsV2.Container> GetContainerAsync(PrmContainerGet args);
|
Task<FrostFsContainerInfo> GetContainerAsync(PrmContainerGet args);
|
||||||
|
|
||||||
IAsyncEnumerable<ContainerId> ListContainersAsync(PrmContainerGetAll? args = null);
|
IAsyncEnumerable<FrostFsContainerId> ListContainersAsync(PrmContainerGetAll? args = null);
|
||||||
|
|
||||||
Task<ContainerId> CreateContainerAsync(PrmContainerCreate args);
|
Task<FrostFsContainerId> CreateContainerAsync(PrmContainerCreate args);
|
||||||
|
|
||||||
Task DeleteContainerAsync(PrmContainerDelete args);
|
Task DeleteContainerAsync(PrmContainerDelete args);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Object
|
#region Object
|
||||||
Task<ObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args);
|
Task<FrostFsObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args);
|
||||||
|
|
||||||
Task<FrostFsObject> GetObjectAsync(PrmObjectGet args);
|
Task<FrostFsObject> GetObjectAsync(PrmObjectGet args);
|
||||||
|
|
||||||
Task<ObjectId> PutObjectAsync(PrmObjectPut putObjectParameters);
|
Task<FrostFsObjectId> PutObjectAsync(PrmObjectPut args);
|
||||||
|
|
||||||
Task<ObjectId> PutSingleObjectAsync(PrmSingleObjectPut args);
|
Task<FrostFsObjectId> PutSingleObjectAsync(PrmSingleObjectPut args);
|
||||||
|
|
||||||
Task DeleteObjectAsync(PrmObjectDelete args);
|
Task DeleteObjectAsync(PrmObjectDelete args);
|
||||||
|
|
||||||
IAsyncEnumerable<ObjectId> SearchObjectsAsync(PrmObjectSearch args);
|
IAsyncEnumerable<FrostFsObjectId> SearchObjectsAsync(PrmObjectSearch args);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Tools
|
#region Tools
|
||||||
ObjectId CalculateObjectId(ObjectHeader header, Context ctx);
|
FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,24 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
using Google.Protobuf;
|
|
||||||
|
|
||||||
using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
|
||||||
using FrostFS.SDK.Cryptography;
|
using FrostFS.SDK.Cryptography;
|
||||||
using FrostFS.SDK.ModelsV2.Enums;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
public static class ContainerMapper
|
public static class ContainerMapper
|
||||||
{
|
{
|
||||||
public static Container.Container ToMessage(this ModelsV2.Container container)
|
public static FrostFsContainerInfo ToModel(this Container.Container container)
|
||||||
{
|
|
||||||
return new Container.Container
|
|
||||||
{
|
|
||||||
BasicAcl = (uint)container.BasicAcl,
|
|
||||||
PlacementPolicy = container.PlacementPolicy.ToMessage(),
|
|
||||||
Nonce = ByteString.CopyFrom(container.Nonce.ToBytes())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ModelsV2.Container ToModel(this Container.Container container)
|
|
||||||
{
|
{
|
||||||
if (!Enum.IsDefined(typeof(BasicAcl),(int)container.BasicAcl))
|
if (!Enum.IsDefined(typeof(BasicAcl),(int)container.BasicAcl))
|
||||||
throw new ArgumentException($"Unknown BasicACL rule. Value: '{container.BasicAcl}'.");
|
throw new ArgumentException($"Unknown BasicACL rule. Value: '{container.BasicAcl}'.");
|
||||||
|
|
||||||
BasicAcl acl = (BasicAcl)container.BasicAcl;
|
BasicAcl acl = (BasicAcl)container.BasicAcl;
|
||||||
|
|
||||||
return new ModelsV2.Container(acl, container.PlacementPolicy.ToModel())
|
return new FrostFsContainerInfo(acl,
|
||||||
{
|
container.PlacementPolicy.ToModel(),
|
||||||
Nonce = container.Nonce.ToUuid(),
|
container.Attributes?.Select(a => new FrostFsAttribute(a.Key, a.Value)).ToList(),
|
||||||
Version = container.Version.ToModel()
|
container.Version?.ToModel(),
|
||||||
};
|
container.OwnerId?.ToModel(),
|
||||||
|
container.Nonce?.ToUuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
using FrostFS.Refs;
|
using FrostFS.Refs;
|
||||||
using FrostFS.SDK.Cryptography;
|
using FrostFS.SDK.Cryptography;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
|
@ -13,16 +15,19 @@ public static class ContainerIdMapper
|
||||||
.SetSlidingExpiration(TimeSpan.FromHours(1))
|
.SetSlidingExpiration(TimeSpan.FromHours(1))
|
||||||
.SetSize(1);
|
.SetSize(1);
|
||||||
|
|
||||||
public static ContainerID ToMessage(this ContainerId model)
|
public static ContainerID ToMessage(this FrostFsContainerId model)
|
||||||
{
|
{
|
||||||
if (!Cache.Containers.TryGetValue(model, out ContainerID? message))
|
if (model.Value == null)
|
||||||
|
throw new ArgumentNullException(nameof(model));
|
||||||
|
|
||||||
|
if (!Cache.Containers.TryGetValue(model.Value, out ContainerID? message))
|
||||||
{
|
{
|
||||||
message = new ContainerID
|
message = new ContainerID
|
||||||
{
|
{
|
||||||
Value = ByteString.CopyFrom(Base58.Decode(model.Value))
|
Value = ByteString.CopyFrom(Base58.Decode(model.Value))
|
||||||
};
|
};
|
||||||
|
|
||||||
Cache.Containers.Set(model, message, _oneHourExpiration);
|
Cache.Containers.Set(model.Value, message, _oneHourExpiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
return message!;
|
return message!;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using FrostFS.Session;
|
using FrostFS.Session;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FrostFS.Netmap;
|
|
||||||
using FrostFS.SDK.ModelsV2.Netmap;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
using FrostFS.Netmap;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public static class NetmapMapper
|
public static class NetmapMapper
|
||||||
{
|
{
|
||||||
public static NetmapSnapshot ToModel(this NetmapSnapshotResponse netmap)
|
public static FrostFsNetmapSnapshot ToModel(this NetmapSnapshotResponse netmap)
|
||||||
{
|
{
|
||||||
return new NetmapSnapshot(
|
return new FrostFsNetmapSnapshot(
|
||||||
netmap.Body.Netmap.Epoch,
|
netmap.Body.Netmap.Epoch,
|
||||||
netmap.Body.Netmap.Nodes
|
netmap.Body.Netmap.Nodes
|
||||||
.Select(n => n.ToModel(netmap.MetaHeader.Version))
|
.Select(n => n.ToModel(netmap.MetaHeader.Version))
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FrostFS.Netmap;
|
|
||||||
using FrostFS.SDK.ModelsV2.Enums;
|
|
||||||
using NodeInfo = FrostFS.SDK.ModelsV2.Netmap.NodeInfo;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
using FrostFS.Netmap;
|
||||||
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public static class NodeInfoMapper
|
public static class NodeInfoMapper
|
||||||
{
|
{
|
||||||
public static NodeInfo ToModel(this LocalNodeInfoResponse.Types.Body node)
|
public static FrostFsNodeInfo ToModel(this LocalNodeInfoResponse.Types.Body node)
|
||||||
{
|
{
|
||||||
return node.NodeInfo.ToModel(node.Version);
|
return node.NodeInfo.ToModel(node.Version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NodeInfo ToModel(this FrostFS.Netmap.NodeInfo nodeInfo, Refs.Version version)
|
public static FrostFsNodeInfo ToModel(this NodeInfo nodeInfo, Refs.Version version)
|
||||||
{
|
{
|
||||||
NodeState state = nodeInfo.State switch
|
NodeState state = nodeInfo.State switch
|
||||||
{
|
{
|
||||||
FrostFS.Netmap.NodeInfo.Types.State.Unspecified => NodeState.Unspecified,
|
NodeInfo.Types.State.Unspecified => NodeState.Unspecified,
|
||||||
FrostFS.Netmap.NodeInfo.Types.State.Online => NodeState.Online,
|
NodeInfo.Types.State.Online => NodeState.Online,
|
||||||
FrostFS.Netmap.NodeInfo.Types.State.Offline => NodeState.Offline,
|
NodeInfo.Types.State.Offline => NodeState.Offline,
|
||||||
FrostFS.Netmap.NodeInfo.Types.State.Maintenance => NodeState.Maintenance,
|
NodeInfo.Types.State.Maintenance => NodeState.Maintenance,
|
||||||
_ => throw new ArgumentException($"Unknown NodeState. Value: '{nodeInfo.State}'.")
|
_ => throw new ArgumentException($"Unknown NodeState. Value: '{nodeInfo.State}'.")
|
||||||
};
|
};
|
||||||
|
|
||||||
return new NodeInfo(
|
return new FrostFsNodeInfo(
|
||||||
version: version.ToModel(),
|
version: version.ToModel(),
|
||||||
state: state,
|
state: state,
|
||||||
addresses: [.. nodeInfo.Addresses],
|
addresses: [.. nodeInfo.Addresses],
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using FrostFS.Netmap;
|
using FrostFS.Netmap;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public static class PlacementPolicyMapper
|
public static class PlacementPolicyMapper
|
||||||
{
|
{
|
||||||
public static PlacementPolicy ToMessage(this ModelsV2.Netmap.PlacementPolicy placementPolicy)
|
public static PlacementPolicy ToMessage(this FrostFsPlacementPolicy placementPolicy)
|
||||||
{
|
{
|
||||||
var pp = new PlacementPolicy
|
var pp = new PlacementPolicy
|
||||||
{
|
{
|
||||||
|
@ -23,9 +24,9 @@ public static class PlacementPolicyMapper
|
||||||
return pp;
|
return pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModelsV2.Netmap.PlacementPolicy ToModel(this PlacementPolicy placementPolicy)
|
public static FrostFsPlacementPolicy ToModel(this PlacementPolicy placementPolicy)
|
||||||
{
|
{
|
||||||
return new ModelsV2.Netmap.PlacementPolicy(
|
return new FrostFsPlacementPolicy(
|
||||||
placementPolicy.Unique,
|
placementPolicy.Unique,
|
||||||
placementPolicy.Replicas.Select(replica => replica.ToModel()).ToArray()
|
placementPolicy.Replicas.Select(replica => replica.ToModel()).ToArray()
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
using FrostFS.Netmap;
|
using FrostFS.Netmap;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public static class ReplicaMapper
|
public static class ReplicaMapper
|
||||||
{
|
{
|
||||||
public static Replica ToMessage(this ModelsV2.Netmap.Replica replica)
|
public static Replica ToMessage(this FrostFsReplica replica)
|
||||||
{
|
{
|
||||||
return new Replica
|
return new Replica
|
||||||
{
|
{
|
||||||
|
@ -13,8 +13,8 @@ public static class ReplicaMapper
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModelsV2.Netmap.Replica ToModel(this Replica replica)
|
public static FrostFsReplica ToModel(this Replica replica)
|
||||||
{
|
{
|
||||||
return new ModelsV2.Netmap.Replica((int)replica.Count, replica.Selector);
|
return new FrostFsReplica((int)replica.Count, replica.Selector);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
internal static class ObjectMapper
|
internal static class ObjectMapper
|
||||||
|
@ -8,7 +6,7 @@ internal static class ObjectMapper
|
||||||
{
|
{
|
||||||
return new FrostFsObject(obj.Header.ToModel())
|
return new FrostFsObject(obj.Header.ToModel())
|
||||||
{
|
{
|
||||||
ObjectId = ObjectId.FromHash(obj.ObjectId.Value.ToByteArray())
|
ObjectId = FrostFsObjectId.FromHash(obj.ObjectId.Value.ToByteArray())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
using FrostFS.Object;
|
using FrostFS.Object;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
public static class ObjectAttributeMapper
|
public static class ObjectAttributeMapper
|
||||||
{
|
{
|
||||||
public static Header.Types.Attribute ToMessage(this ObjectAttribute attribute)
|
public static Header.Types.Attribute ToMessage(this FrostFsAttribute attribute)
|
||||||
{
|
{
|
||||||
return new Header.Types.Attribute
|
return new Header.Types.Attribute
|
||||||
{
|
{
|
||||||
|
@ -14,8 +13,8 @@ public static class ObjectAttributeMapper
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectAttribute ToModel(this Header.Types.Attribute attribute)
|
public static FrostFsAttribute ToModel(this Header.Types.Attribute attribute)
|
||||||
{
|
{
|
||||||
return new ObjectAttribute(attribute.Key, attribute.Value);
|
return new FrostFsAttribute(attribute.Key, attribute.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using FrostFS.Object;
|
using FrostFS.Object;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using MatchType = FrostFS.Object.MatchType;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
|
@ -11,11 +10,11 @@ public static class ObjectFilterMapper
|
||||||
{
|
{
|
||||||
var objMatchTypeName = filter.MatchType switch
|
var objMatchTypeName = filter.MatchType switch
|
||||||
{
|
{
|
||||||
ModelsV2.Enums.ObjectMatchType.Unspecified => MatchType.Unspecified,
|
FrostFsObjectMatchType.Unspecified => MatchType.Unspecified,
|
||||||
ModelsV2.Enums.ObjectMatchType.Equals => MatchType.StringEqual,
|
FrostFsObjectMatchType.Equals => MatchType.StringEqual,
|
||||||
ModelsV2.Enums.ObjectMatchType.NotEquals => MatchType.StringNotEqual,
|
FrostFsObjectMatchType.NotEquals => MatchType.StringNotEqual,
|
||||||
ModelsV2.Enums.ObjectMatchType.KeyAbsent => MatchType.NotPresent,
|
FrostFsObjectMatchType.KeyAbsent => MatchType.NotPresent,
|
||||||
ModelsV2.Enums.ObjectMatchType.StartsWith => MatchType.CommonPrefix,
|
FrostFsObjectMatchType.StartsWith => MatchType.CommonPrefix,
|
||||||
|
|
||||||
_ => throw new ArgumentException($"Unknown MatchType. Value: '{filter.MatchType}'.")
|
_ => throw new ArgumentException($"Unknown MatchType. Value: '{filter.MatchType}'.")
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,75 +1,28 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using FrostFS.Object;
|
using FrostFS.Object;
|
||||||
using FrostFS.SDK.Cryptography;
|
using FrostFS.SDK.Cryptography;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using Google.Protobuf;
|
|
||||||
using ObjectType = FrostFS.Object.ObjectType;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
public static class ObjectHeaderMapper
|
public static class ObjectHeaderMapper
|
||||||
{
|
{
|
||||||
public static Header ToMessage(this ObjectHeader header)
|
public static FrostFsObjectHeader ToModel(this Header header)
|
||||||
{
|
{
|
||||||
var objTypeName = header.ObjectType switch
|
var objTypeName = header.ObjectType switch
|
||||||
{
|
{
|
||||||
ModelsV2.Enums.ObjectType.Regular => ObjectType.Regular,
|
ObjectType.Regular => FrostFsObjectType.Regular,
|
||||||
ModelsV2.Enums.ObjectType.Lock => ObjectType.Lock,
|
ObjectType.Lock => FrostFsObjectType.Lock,
|
||||||
ModelsV2.Enums.ObjectType.Tombstone => ObjectType.Tombstone,
|
ObjectType.Tombstone => FrostFsObjectType.Tombstone,
|
||||||
_ => throw new ArgumentException($"Unknown ObjectType. Value: '{header.ObjectType}'.")
|
_ => throw new ArgumentException($"Unknown ObjectType. Value: '{header.ObjectType}'.")
|
||||||
};
|
};
|
||||||
|
|
||||||
var head = new Header
|
FrostFsSplit? split = null;
|
||||||
{
|
|
||||||
OwnerId = header!.OwnerId != null ? header.OwnerId.ToMessage() : null,
|
|
||||||
Version = header!.Version != null ? header.Version.ToMessage() : null,
|
|
||||||
ContainerId = header.ContainerId.ToMessage(),
|
|
||||||
ObjectType = objTypeName,
|
|
||||||
PayloadLength = header.PayloadLength
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var attribute in header.Attributes)
|
|
||||||
{
|
|
||||||
head.Attributes.Add(attribute.ToMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
var split = header.Split;
|
|
||||||
if (split != null)
|
|
||||||
{
|
|
||||||
head.Split = new Header.Types.Split
|
|
||||||
{
|
|
||||||
SplitId = split.SplitId != null ? ByteString.CopyFrom(split.SplitId.ToBinary()) : null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ObjectHeader ToModel(this Header header)
|
|
||||||
{
|
|
||||||
var objTypeName = header.ObjectType switch
|
|
||||||
{
|
|
||||||
ObjectType.Regular => ModelsV2.Enums.ObjectType.Regular,
|
|
||||||
ObjectType.Lock => ModelsV2.Enums.ObjectType.Lock,
|
|
||||||
ObjectType.Tombstone => ModelsV2.Enums.ObjectType.Tombstone,
|
|
||||||
_ => throw new ArgumentException($"Unknown ObjectType. Value: '{header.ObjectType}'.")
|
|
||||||
};
|
|
||||||
|
|
||||||
var model = new ObjectHeader(
|
|
||||||
new ContainerId(Base58.Encode(header.ContainerId.Value.ToByteArray())),
|
|
||||||
objTypeName,
|
|
||||||
header.Attributes.Select(attribute => attribute.ToModel()).ToArray()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
PayloadLength = header.PayloadLength,
|
|
||||||
Version = header.Version.ToModel(),
|
|
||||||
OwnerId = header.OwnerId.ToModel()
|
|
||||||
};
|
|
||||||
|
|
||||||
if (header.Split != null)
|
if (header.Split != null)
|
||||||
{
|
{
|
||||||
model.Split = new Split(new SplitId(header.Split.SplitId.ToUuid()))
|
split = new FrostFsSplit(new SplitId(header.Split.SplitId.ToUuid()))
|
||||||
{
|
{
|
||||||
Parent = header.Split.Parent?.ToModel(),
|
Parent = header.Split.Parent?.ToModel(),
|
||||||
ParentHeader = header.Split.ParentHeader?.ToModel(),
|
ParentHeader = header.Split.ParentHeader?.ToModel(),
|
||||||
|
@ -77,9 +30,20 @@ public static class ObjectHeaderMapper
|
||||||
};
|
};
|
||||||
|
|
||||||
if (header.Split.Children.Count != 0)
|
if (header.Split.Children.Count != 0)
|
||||||
model.Split.Children.AddRange(header.Split.Children.Select(x => x.ToModel()));
|
split.Children.AddRange(header.Split.Children.Select(x => x.ToModel()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var model = new FrostFsObjectHeader(
|
||||||
|
new FrostFsContainerId(Base58.Encode(header.ContainerId.Value.ToByteArray())),
|
||||||
|
objTypeName,
|
||||||
|
header.Attributes.Select(attribute => attribute.ToModel()).ToArray(),
|
||||||
|
split,
|
||||||
|
header.OwnerId.ToModel(),
|
||||||
|
header.Version.ToModel())
|
||||||
|
{
|
||||||
|
PayloadLength = header.PayloadLength,
|
||||||
|
};
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
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;
|
||||||
|
|
||||||
public static class ObjectIdMapper
|
public static class ObjectIdMapper
|
||||||
{
|
{
|
||||||
public static ObjectID ToMessage(this ObjectId objectId)
|
public static ObjectID ToMessage(this FrostFsObjectId objectId)
|
||||||
{
|
{
|
||||||
return new ObjectID
|
return new ObjectID
|
||||||
{
|
{
|
||||||
|
@ -14,8 +14,8 @@ public static class ObjectIdMapper
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectId ToModel(this ObjectID objectId)
|
public static FrostFsObjectId ToModel(this ObjectID objectId)
|
||||||
{
|
{
|
||||||
return ObjectId.FromHash(objectId.Value.ToByteArray());
|
return FrostFsObjectId.FromHash(objectId.Value.ToByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
using FrostFS.Refs;
|
using FrostFS.Refs;
|
||||||
using FrostFS.SDK.Cryptography;
|
using FrostFS.SDK.Cryptography;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
|
@ -13,7 +15,7 @@ public static class OwnerIdMapper
|
||||||
.SetSlidingExpiration(TimeSpan.FromHours(1))
|
.SetSlidingExpiration(TimeSpan.FromHours(1))
|
||||||
.SetSize(1);
|
.SetSize(1);
|
||||||
|
|
||||||
public static OwnerID ToMessage(this OwnerId model)
|
public static OwnerID ToMessage(this FrostFsOwner model)
|
||||||
{
|
{
|
||||||
if (!Cache.Owners.TryGetValue(model, out OwnerID? message))
|
if (!Cache.Owners.TryGetValue(model, out OwnerID? message))
|
||||||
{
|
{
|
||||||
|
@ -28,11 +30,11 @@ public static class OwnerIdMapper
|
||||||
return message!;
|
return message!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OwnerId ToModel(this OwnerID message)
|
public static FrostFsOwner ToModel(this OwnerID message)
|
||||||
{
|
{
|
||||||
if (!Cache.Owners.TryGetValue(message, out OwnerId? model))
|
if (!Cache.Owners.TryGetValue(message, out FrostFsOwner? model))
|
||||||
{
|
{
|
||||||
model = new OwnerId(Base58.Encode(message.Value.ToByteArray()));
|
model = new FrostFsOwner(Base58.Encode(message.Value.ToByteArray()));
|
||||||
|
|
||||||
Cache.Owners.Set(message, model, _oneHourExpiration);
|
Cache.Owners.Set(message, model, _oneHourExpiration);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
public static class SignatureMapper
|
public static class SignatureMapper
|
||||||
{
|
{
|
||||||
public static Refs.Signature ToMessage(this Signature signature)
|
public static Refs.Signature ToMessage(this FrostFsSignature signature)
|
||||||
{
|
{
|
||||||
var scheme = signature.Scheme switch
|
var scheme = signature.Scheme switch
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
using System;
|
using System;
|
||||||
using FrostFS.SDK.ModelsV2.Enums;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
public static class StatusMapper
|
public static class StatusMapper
|
||||||
{
|
{
|
||||||
public static ModelsV2.ResponseStatus ToModel(this Status.Status status)
|
public static FrostFsResponseStatus ToModel(this Status.Status status)
|
||||||
{
|
{
|
||||||
if (status is null)
|
if (status is null)
|
||||||
return new ModelsV2.ResponseStatus(StatusCode.Success);
|
return new FrostFsResponseStatus(FrostFsStatusCode.Success);
|
||||||
|
|
||||||
var codeName = Enum.GetName(typeof(StatusCode), status.Code);
|
var codeName = Enum.GetName(typeof(FrostFsStatusCode), status.Code);
|
||||||
|
|
||||||
return codeName is null
|
return codeName is null
|
||||||
? throw new ArgumentException($"Unknown StatusCode. Value: '{status.Code}'.")
|
? throw new ArgumentException($"Unknown StatusCode. Value: '{status.Code}'.")
|
||||||
: new ModelsV2.ResponseStatus((StatusCode)Enum.Parse(typeof(StatusCode), codeName), status.Message);
|
: new FrostFsResponseStatus((FrostFsStatusCode)status.Code, status.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Version = FrostFS.Refs.Version;
|
|
||||||
|
using FrostFS.Refs;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ public static class VersionMapper
|
||||||
private static readonly Hashtable _cacheModels = [];
|
private static readonly Hashtable _cacheModels = [];
|
||||||
private static SpinLock _spinlock = new();
|
private static SpinLock _spinlock = new();
|
||||||
|
|
||||||
public static Version ToMessage(this ModelsV2.Version model)
|
public static Version ToMessage(this FrostFsVersion model)
|
||||||
{
|
{
|
||||||
var key = model.Major << 16 + model.Minor;
|
var key = model.Major << 16 + model.Minor;
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ public static class VersionMapper
|
||||||
}
|
}
|
||||||
catch (System.ArgumentException)
|
catch (System.ArgumentException)
|
||||||
{
|
{
|
||||||
// ignore attempt to add duplicate error.
|
// ignore attempt to add duplicate
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -43,7 +44,7 @@ public static class VersionMapper
|
||||||
return (Version)_cacheMessages[key];
|
return (Version)_cacheMessages[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModelsV2.Version ToModel(this Version message)
|
public static FrostFsVersion ToModel(this Version message)
|
||||||
{
|
{
|
||||||
var key = (int)message.Major << 16 + (int)message.Minor;
|
var key = (int)message.Major << 16 + (int)message.Minor;
|
||||||
|
|
||||||
|
@ -53,14 +54,14 @@ public static class VersionMapper
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_spinlock.Enter(ref lockTaken);
|
_spinlock.Enter(ref lockTaken);
|
||||||
var model = new ModelsV2.Version((int)message.Major, (int)message.Minor);
|
var model = new FrostFsVersion((int)message.Major, (int)message.Minor);
|
||||||
|
|
||||||
_cacheModels.Add(key, model);
|
_cacheModels.Add(key, model);
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
catch (System.ArgumentException)
|
catch (System.ArgumentException)
|
||||||
{
|
{
|
||||||
// ignore attempt to add duplicate error.
|
// ignore attempt to add duplicate
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -69,6 +70,6 @@ public static class VersionMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ModelsV2.Version)_cacheModels[key];
|
return (FrostFsVersion)_cacheModels[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
63
src/FrostFS.SDK.ClientV2/Models/Client/ClientSettings.cs
Normal file
63
src/FrostFS.SDK.ClientV2/Models/Client/ClientSettings.cs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class ClientSettings
|
||||||
|
{
|
||||||
|
protected static readonly string errorTemplate = "{0} is required parameter";
|
||||||
|
|
||||||
|
public string Host { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public virtual void Validate()
|
||||||
|
{
|
||||||
|
var errors = CheckFields();
|
||||||
|
if (errors != null)
|
||||||
|
ThrowException(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<string>? CheckFields()
|
||||||
|
{
|
||||||
|
List<string>? errors = null;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(Host))
|
||||||
|
(errors ??= []).Add(string.Format(errorTemplate, nameof(Host)));
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void ThrowException(List<string> errors)
|
||||||
|
{
|
||||||
|
StringBuilder messages = new();
|
||||||
|
|
||||||
|
foreach (var error in errors)
|
||||||
|
{
|
||||||
|
messages.AppendLine(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException(messages.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SingleOwnerClientSettings : ClientSettings
|
||||||
|
{
|
||||||
|
public string Key { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public override void Validate()
|
||||||
|
{
|
||||||
|
var errors = CheckFields();
|
||||||
|
if (errors != null)
|
||||||
|
ThrowException(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected new List<string>? CheckFields()
|
||||||
|
{
|
||||||
|
List<string>? errors = base.CheckFields();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(Key))
|
||||||
|
(errors ??= []).Add(string.Format(errorTemplate, nameof(Key)));
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
using FrostFS.Refs;
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
|
||||||
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
using FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsContainerId
|
||||||
|
{
|
||||||
|
private string? modelId;
|
||||||
|
private ContainerID? containerID;
|
||||||
|
|
||||||
|
public FrostFsContainerId(string id)
|
||||||
|
{
|
||||||
|
this.modelId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal FrostFsContainerId(ContainerID id)
|
||||||
|
{
|
||||||
|
this.containerID = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.modelId != null)
|
||||||
|
return this.modelId;
|
||||||
|
|
||||||
|
if (containerID != null)
|
||||||
|
{
|
||||||
|
this.modelId = Base58.Encode(containerID.Value.ToByteArray());
|
||||||
|
return this.modelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidObjectException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal ContainerID ContainerID
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.containerID != null)
|
||||||
|
return this.containerID;
|
||||||
|
|
||||||
|
if (modelId != null)
|
||||||
|
{
|
||||||
|
this.containerID = this.ToMessage();
|
||||||
|
return this.containerID;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidObjectException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using FrostFS.SDK.ClientV2;
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
|
using Google.Protobuf;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsContainerInfo
|
||||||
|
{
|
||||||
|
private Container.Container.Types.Attribute[]? grpsAttributes;
|
||||||
|
private List<FrostFsAttribute>? attributes;
|
||||||
|
private FrostFsPlacementPolicy? placementPolicy;
|
||||||
|
private Guid? nonce;
|
||||||
|
|
||||||
|
private Container.Container container;
|
||||||
|
|
||||||
|
public FrostFsContainerInfo(
|
||||||
|
BasicAcl basicAcl,
|
||||||
|
FrostFsPlacementPolicy placementPolicy,
|
||||||
|
List<FrostFsAttribute>? attributes = null,
|
||||||
|
FrostFsVersion? version = null,
|
||||||
|
FrostFsOwner? owner = null,
|
||||||
|
Guid? nonce = null)
|
||||||
|
{
|
||||||
|
BasicAcl = basicAcl;
|
||||||
|
this.placementPolicy = placementPolicy;
|
||||||
|
this.attributes = attributes;
|
||||||
|
Version = version;
|
||||||
|
Owner = owner;
|
||||||
|
this.nonce = nonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal FrostFsContainerInfo(Container.Container container)
|
||||||
|
{
|
||||||
|
this.container = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guid Nonce
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
nonce ??= container?.Nonce != null ? container.Nonce.ToUuid() : Guid.NewGuid();
|
||||||
|
return nonce.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BasicAcl BasicAcl { get; private set; }
|
||||||
|
|
||||||
|
public FrostFsPlacementPolicy? PlacementPolicy
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
placementPolicy ??= container.PlacementPolicy?.ToModel();
|
||||||
|
return placementPolicy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FrostFsAttribute>? Attributes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (attributes == null && grpsAttributes != null)
|
||||||
|
attributes = grpsAttributes.Select(a => new FrostFsAttribute(a.Key, a.Value)).ToList();
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrostFsVersion? Version { get; private set; }
|
||||||
|
|
||||||
|
public FrostFsOwner? Owner { get; private set; }
|
||||||
|
|
||||||
|
internal Container.Container.Types.Attribute[]? GetGrpsAttributes()
|
||||||
|
{
|
||||||
|
grpsAttributes ??= Attributes?
|
||||||
|
.Select(a => new Container.Container.Types.Attribute { Key = a.Key, Value = a.Value })
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
return grpsAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Container.Container GetContainer()
|
||||||
|
{
|
||||||
|
if (this.container == null)
|
||||||
|
{
|
||||||
|
this.container = new Container.Container()
|
||||||
|
{
|
||||||
|
BasicAcl = (uint)BasicAcl,
|
||||||
|
PlacementPolicy = PlacementPolicy.ToMessage(),
|
||||||
|
Nonce = ByteString.CopyFrom(Nonce.ToBytes()),
|
||||||
|
OwnerId = Owner?.OwnerID,
|
||||||
|
Version = Version?.Version
|
||||||
|
};
|
||||||
|
|
||||||
|
var attribs = GetGrpsAttributes();
|
||||||
|
if (attribs != null)
|
||||||
|
this.container.Attributes.AddRange(attribs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.container;
|
||||||
|
}
|
||||||
|
}
|
21
src/FrostFS.SDK.ClientV2/Models/Enums/BasicAcl.cs
Normal file
21
src/FrostFS.SDK.ClientV2/Models/Enums/BasicAcl.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public enum BasicAcl
|
||||||
|
{
|
||||||
|
[Description("Not defined ACL")]
|
||||||
|
NotDefined = 0x00000000,
|
||||||
|
|
||||||
|
[Description("Basic ACL for private container")]
|
||||||
|
Private = 0x1C8C8CCC,
|
||||||
|
|
||||||
|
[Description("Basic ACL for public RO container")]
|
||||||
|
PublicRO = 0x1FBF8CFF,
|
||||||
|
|
||||||
|
[Description("Basic ACL for public RW container")]
|
||||||
|
PublicRW = 0x1FBFBFFF,
|
||||||
|
|
||||||
|
[Description("Basic ACL for public append container")]
|
||||||
|
PublicAppend = 0x1FBF9FFF,
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
namespace FrostFS.SDK.ModelsV2.Enums;
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
public enum ObjectMatchType
|
public enum FrostFsObjectMatchType
|
||||||
{
|
{
|
||||||
Unspecified = 0,
|
Unspecified = 0,
|
||||||
Equals = 1,
|
Equals = 1,
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public enum FrostFsObjectType
|
||||||
|
{
|
||||||
|
Regular = 0,
|
||||||
|
Tombstone = 1,
|
||||||
|
Lock = 3
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
namespace FrostFS.SDK.ModelsV2.Enums;
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
public enum StatusCode
|
public enum FrostFsStatusCode
|
||||||
{
|
{
|
||||||
Success = 0,
|
Success = 0,
|
||||||
Internal = 1024,
|
Internal = 1024,
|
9
src/FrostFS.SDK.ClientV2/Models/Enums/NodeState.cs
Normal file
9
src/FrostFS.SDK.ClientV2/Models/Enums/NodeState.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public enum NodeState
|
||||||
|
{
|
||||||
|
Unspecified = 0,
|
||||||
|
Online = 1,
|
||||||
|
Offline = 2,
|
||||||
|
Maintenance = 3
|
||||||
|
}
|
8
src/FrostFS.SDK.ClientV2/Models/Enums/SignatureScheme.cs
Normal file
8
src/FrostFS.SDK.ClientV2/Models/Enums/SignatureScheme.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public enum SignatureScheme
|
||||||
|
{
|
||||||
|
EcdsaSha512,
|
||||||
|
EcdsaRfc6979Sha256,
|
||||||
|
EcdsaRfc6979Sha256WalletConnect
|
||||||
|
}
|
7
src/FrostFS.SDK.ClientV2/Models/Misc/CallStatistics.cs
Normal file
7
src/FrostFS.SDK.ClientV2/Models/Misc/CallStatistics.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class CallStatistics
|
||||||
|
{
|
||||||
|
public string? MethodName { get; set; }
|
||||||
|
public long ElapsedMicroSeconds { get; set; }
|
||||||
|
}
|
20
src/FrostFS.SDK.ClientV2/Models/Misc/CheckSum.cs
Normal file
20
src/FrostFS.SDK.ClientV2/Models/Misc/CheckSum.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class CheckSum
|
||||||
|
{
|
||||||
|
// type is always Sha256
|
||||||
|
public byte[]? Hash { get; set; }
|
||||||
|
|
||||||
|
public static CheckSum CreateCheckSum(byte[] content)
|
||||||
|
{
|
||||||
|
return new CheckSum { Hash = content.Sha256() };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return BitConverter.ToString(Hash).Replace("-", "");
|
||||||
|
}
|
||||||
|
}
|
52
src/FrostFS.SDK.ClientV2/Models/Misc/Constants.cs
Normal file
52
src/FrostFS.SDK.ClientV2/Models/Misc/Constants.cs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class Constants
|
||||||
|
{
|
||||||
|
public const int ObjectChunkSize = 3 * (1 << 20);
|
||||||
|
public const int Sha256HashLength = 32;
|
||||||
|
|
||||||
|
// HeaderPrefix is a prefix of key to object header value or property.
|
||||||
|
public const string HeaderPrefix = "$Object:";
|
||||||
|
|
||||||
|
// FilterHeaderVersion is a filter key to "version" field of the object header.
|
||||||
|
public const string FilterHeaderVersion = HeaderPrefix + "version";
|
||||||
|
|
||||||
|
// FilterHeaderObjectID is a filter key to "object_id" field of the object.
|
||||||
|
public const string FilterHeaderObjectID = HeaderPrefix + "objectID";
|
||||||
|
|
||||||
|
// FilterHeaderContainerID is a filter key to "container_id" field of the object header.
|
||||||
|
public const string FilterHeaderContainerID = HeaderPrefix + "containerID";
|
||||||
|
|
||||||
|
// FilterHeaderOwnerID is a filter key to "owner_id" field of the object header.
|
||||||
|
public const string FilterHeaderOwnerID = HeaderPrefix + "ownerID";
|
||||||
|
|
||||||
|
// FilterHeaderCreationEpoch is a filter key to "creation_epoch" field of the object header.
|
||||||
|
public const string FilterHeaderCreationEpoch = HeaderPrefix + "creationEpoch";
|
||||||
|
|
||||||
|
// FilterHeaderPayloadLength is a filter key to "payload_length" field of the object header.
|
||||||
|
public const string FilterHeaderPayloadLength = HeaderPrefix + "payloadLength";
|
||||||
|
|
||||||
|
// FilterHeaderPayloadHash is a filter key to "payload_hash" field of the object header.
|
||||||
|
public const string FilterHeaderPayloadHash = HeaderPrefix + "payloadHash";
|
||||||
|
|
||||||
|
// FilterHeaderObjectType is a filter key to "object_type" field of the object header.
|
||||||
|
public const string FilterHeaderObjectType = HeaderPrefix + "objectType";
|
||||||
|
|
||||||
|
// FilterHeaderHomomorphicHash is a filter key to "homomorphic_hash" field of the object header.
|
||||||
|
public const string FilterHeaderHomomorphicHash = HeaderPrefix + "homomorphicHash";
|
||||||
|
|
||||||
|
// FilterHeaderParent is a filter key to "split.parent" field of the object header.
|
||||||
|
public const string FilterHeaderParent = HeaderPrefix + "split.parent";
|
||||||
|
|
||||||
|
// FilterHeaderSplitID is a filter key to "split.splitID" field of the object header.
|
||||||
|
public const string FilterHeaderSplitID = HeaderPrefix + "split.splitID";
|
||||||
|
|
||||||
|
// FilterHeaderECParent is a filter key to "ec.parent" field of the object header.
|
||||||
|
public const string FilterHeaderECParent = HeaderPrefix + "ec.parent";
|
||||||
|
|
||||||
|
// FilterPropertyRoot is a filter key to check if regular object is on top of split hierarchy.
|
||||||
|
public const string FilterHeaderRoot = HeaderPrefix + "ROOT";
|
||||||
|
|
||||||
|
// FilterPropertyPhy is a filter key to check if an object physically stored on a node.
|
||||||
|
public const string FilterHeaderPhy = HeaderPrefix + "PHY";
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsNetmapSnapshot(ulong epoch, IReadOnlyList<FrostFsNodeInfo> nodeInfoCollection)
|
||||||
|
{
|
||||||
|
public ulong Epoch { get; private set; } = epoch;
|
||||||
|
|
||||||
|
public IReadOnlyList<FrostFsNodeInfo> NodeInfoCollection { get; private set; } = nodeInfoCollection;
|
||||||
|
}
|
|
@ -1,18 +1,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FrostFS.SDK.ModelsV2.Enums;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ModelsV2.Netmap;
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
public class NodeInfo(
|
public class FrostFsNodeInfo(
|
||||||
Version version,
|
FrostFsVersion version,
|
||||||
NodeState state,
|
NodeState state,
|
||||||
IReadOnlyCollection<string> addresses,
|
IReadOnlyCollection<string> addresses,
|
||||||
IReadOnlyDictionary<string, string> attributes,
|
IReadOnlyDictionary<string, string> attributes,
|
||||||
ReadOnlyMemory<byte> publicKey)
|
ReadOnlyMemory<byte> publicKey)
|
||||||
{
|
{
|
||||||
public NodeState State { get; private set; } = state;
|
public NodeState State { get; private set; } = state;
|
||||||
public Version Version { get; private set; } = version;
|
public FrostFsVersion Version { get; private set; } = version;
|
||||||
public IReadOnlyCollection<string> Addresses { get; private set; } = addresses;
|
public IReadOnlyCollection<string> Addresses { get; private set; } = addresses;
|
||||||
public IReadOnlyDictionary<string, string> Attributes { get; private set; } = attributes;
|
public IReadOnlyDictionary<string, string> Attributes { get; private set; } = attributes;
|
||||||
public ReadOnlyMemory<byte> PublicKey { get; private set; } = publicKey;
|
public ReadOnlyMemory<byte> PublicKey { get; private set; } = publicKey;
|
|
@ -1,14 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ModelsV2.Netmap;
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
public class PlacementPolicy(bool unique, params Replica[] replicas) : IComparable<PlacementPolicy>
|
public class FrostFsPlacementPolicy(bool unique, params FrostFsReplica[] replicas) : IComparable<FrostFsPlacementPolicy>
|
||||||
{
|
{
|
||||||
public Replica[] Replicas { get; private set; } = replicas;
|
public FrostFsReplica[] Replicas { get; private set; } = replicas;
|
||||||
public bool Unique { get; private set; } = unique;
|
public bool Unique { get; private set; } = unique;
|
||||||
|
|
||||||
public int CompareTo(PlacementPolicy other)
|
public int CompareTo(FrostFsPlacementPolicy other)
|
||||||
{
|
{
|
||||||
var notEqual = other == null
|
var notEqual = other == null
|
||||||
|| Unique != other.Unique
|
|| Unique != other.Unique
|
|
@ -1,11 +1,11 @@
|
||||||
namespace FrostFS.SDK.ModelsV2.Netmap;
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
public class Replica
|
public class FrostFsReplica
|
||||||
{
|
{
|
||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
public string Selector { get; set; }
|
public string Selector { get; set; }
|
||||||
|
|
||||||
public Replica(int count, string? selector = null)
|
public FrostFsReplica(int count, string? selector = null)
|
||||||
{
|
{
|
||||||
selector ??= string.Empty;
|
selector ??= string.Empty;
|
||||||
|
|
31
src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsVersion.cs
Normal file
31
src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsVersion.cs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
using FrostFS.Refs;
|
||||||
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsVersion(int major, int minor)
|
||||||
|
{
|
||||||
|
public Version version;
|
||||||
|
|
||||||
|
public int Major { get; set; } = major;
|
||||||
|
public int Minor { get; set; } = minor;
|
||||||
|
|
||||||
|
internal Version Version
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
this.version ??= this.ToMessage();
|
||||||
|
return this.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSupported(FrostFsVersion version)
|
||||||
|
{
|
||||||
|
return Major == version.Major;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"v{Major}.{Minor}";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsAttribute(string key, string value)
|
||||||
|
{
|
||||||
|
public string Key { get; set; } = key;
|
||||||
|
|
||||||
|
public string Value { get; set; } = value;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsLargeObject(FrostFsContainerId container) : FrostFsObject(container)
|
||||||
|
{
|
||||||
|
public ulong PayloadLength
|
||||||
|
{
|
||||||
|
get { return Header!.PayloadLength; }
|
||||||
|
}
|
||||||
|
}
|
13
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsLinkObject.cs
Normal file
13
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsLinkObject.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsLinkObject : FrostFsObject
|
||||||
|
{
|
||||||
|
public FrostFsLinkObject(FrostFsContainerId containerId, SplitId splitId, FrostFsObjectHeader largeObjectHeader)
|
||||||
|
: base(containerId)
|
||||||
|
{
|
||||||
|
Header!.Split = new FrostFsSplit(splitId)
|
||||||
|
{
|
||||||
|
ParentHeader = largeObjectHeader
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
64
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObject.cs
Normal file
64
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObject.cs
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates new instance from <c>ObjectHeader</c>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="header"></param> <summary>
|
||||||
|
public FrostFsObject(FrostFsObjectHeader header)
|
||||||
|
{
|
||||||
|
Header = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates new instance with specified parameters
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container"></param>
|
||||||
|
/// <param name="objectType"></param>
|
||||||
|
public FrostFsObject(FrostFsContainerId container, FrostFsObjectType objectType = FrostFsObjectType.Regular)
|
||||||
|
{
|
||||||
|
Header = new FrostFsObjectHeader(containerId: container, type: objectType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Header contains metadata for the object
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
public FrostFsObjectHeader Header { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The value is calculated internally as a hash of ObjectHeader. Do not use pre-calculated value is the object has been changed.
|
||||||
|
/// </summary>
|
||||||
|
public FrostFsObjectId? ObjectId
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The size of payload cannot exceed <c>MaxObjectSize</c> value from <c>NetworkSettings</c>
|
||||||
|
/// Used only for PutSingleObject method
|
||||||
|
/// </summary>
|
||||||
|
/// <value>Buffer for output data</value>
|
||||||
|
public byte[] Payload { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A payload is obtained via stream reader
|
||||||
|
/// </summary>
|
||||||
|
/// <value>Reader for received data</value>
|
||||||
|
public IObjectReader? ObjectReader { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applied only for the last Object in chain in case of manual multipart uploading
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="largeObject">Parent for multipart object</param>
|
||||||
|
public void SetParent(FrostFsObjectHeader largeObjectHeader)
|
||||||
|
{
|
||||||
|
if (Header?.Split == null)
|
||||||
|
throw new Exception("The object is not initialized properly");
|
||||||
|
|
||||||
|
Header.Split.ParentHeader = largeObjectHeader;
|
||||||
|
}
|
||||||
|
}
|
111
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectFilter.cs
Normal file
111
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectFilter.cs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public interface IObjectFilter
|
||||||
|
{
|
||||||
|
public FrostFsObjectMatchType MatchType { get; set; }
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
string? GetSerializedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class FrostFsObjectFilter<T>(FrostFsObjectMatchType matchType, string key, T value) : IObjectFilter
|
||||||
|
{
|
||||||
|
public FrostFsObjectMatchType MatchType { get; set; } = matchType;
|
||||||
|
public string Key { get; set; } = key;
|
||||||
|
|
||||||
|
public T Value { get; set; } = value;
|
||||||
|
|
||||||
|
public string? GetSerializedValue()
|
||||||
|
{
|
||||||
|
return Value?.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by Attribute
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="key">Attribute key</param>
|
||||||
|
/// <param name="value">Attribute value</param>
|
||||||
|
public class FilterByAttribute(FrostFsObjectMatchType matchType, string key, string value) : FrostFsObjectFilter<string>(matchType, key, value) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by ObjectId
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="objectId">ObjectId</param>
|
||||||
|
public class FilterByObjectId(FrostFsObjectMatchType matchType, FrostFsObjectId objectId) : FrostFsObjectFilter<FrostFsObjectId>(matchType, Constants.FilterHeaderObjectID, objectId) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by OwnerId
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="ownerId">ObjectId</param>
|
||||||
|
public class FilterByOwnerId(FrostFsObjectMatchType matchType, FrostFsOwner ownerId) : FrostFsObjectFilter<FrostFsOwner>(matchType, Constants.FilterHeaderOwnerID, ownerId) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by Version
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="version">Version</param>
|
||||||
|
public class FilterByVersion(FrostFsObjectMatchType matchType, FrostFsVersion version) : FrostFsObjectFilter<FrostFsVersion>(matchType, Constants.FilterHeaderVersion, version) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by ContainerId
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="containerId">ContainerId</param>
|
||||||
|
public class FilterByContainerId(FrostFsObjectMatchType matchType, FrostFsContainerId containerId) : FrostFsObjectFilter<FrostFsContainerId>(matchType, Constants.FilterHeaderContainerID, containerId) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by creation Epoch
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="epoch">Creation Epoch</param>
|
||||||
|
public class FilterByEpoch(FrostFsObjectMatchType matchType, ulong epoch) : FrostFsObjectFilter<ulong>(matchType, Constants.FilterHeaderCreationEpoch, epoch) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by Payload Length
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="payloadLength">Payload Length</param>
|
||||||
|
public class FilterByPayloadLength(FrostFsObjectMatchType matchType, ulong payloadLength) : FrostFsObjectFilter<ulong>(matchType, Constants.FilterHeaderPayloadLength, payloadLength) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by Payload Hash
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="payloadHash">Payload Hash</param>
|
||||||
|
public class FilterByPayloadHash(FrostFsObjectMatchType matchType, CheckSum payloadHash) : FrostFsObjectFilter<CheckSum>(matchType, Constants.FilterHeaderPayloadHash, payloadHash) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by Parent
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="parentId">Parent</param>
|
||||||
|
public class FilterByParent(FrostFsObjectMatchType matchType, FrostFsObjectId parentId) : FrostFsObjectFilter<FrostFsObjectId>(matchType, Constants.FilterHeaderParent, parentId) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by SplitId
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="splitId">SplitId</param>
|
||||||
|
public class FilterBySplitId(FrostFsObjectMatchType matchType, SplitId splitId) : FrostFsObjectFilter<SplitId>(matchType, Constants.FilterHeaderSplitID, splitId) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search by Payload Hash
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matchType">Match type</param>
|
||||||
|
/// <param name="ecParentId">Payload Hash</param>
|
||||||
|
public class FilterByECParent(FrostFsObjectMatchType matchType, FrostFsObjectId ecParentId) : FrostFsObjectFilter<FrostFsObjectId>(matchType, Constants.FilterHeaderECParent, ecParentId) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search Root objects
|
||||||
|
/// </summary>
|
||||||
|
public class FilterByRootObject() : FrostFsObjectFilter<string>(FrostFsObjectMatchType.Unspecified, Constants.FilterHeaderRoot, string.Empty) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates filter to search objects that are physically stored on the server
|
||||||
|
/// </summary
|
||||||
|
public class FilterByPhysicallyStored() : FrostFsObjectFilter<string>(FrostFsObjectMatchType.Unspecified, Constants.FilterHeaderPhy, string.Empty) { }
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using FrostFS.Object;
|
||||||
|
|
||||||
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsObjectHeader(
|
||||||
|
FrostFsContainerId containerId,
|
||||||
|
FrostFsObjectType type = FrostFsObjectType.Regular,
|
||||||
|
FrostFsAttribute[]? attributes = null,
|
||||||
|
FrostFsSplit? split = null,
|
||||||
|
FrostFsOwner? owner = null,
|
||||||
|
FrostFsVersion? version = null)
|
||||||
|
{
|
||||||
|
private Header header;
|
||||||
|
private Container.Container.Types.Attribute[]? grpsAttributes;
|
||||||
|
|
||||||
|
public List<FrostFsAttribute> Attributes { get; internal set; } = attributes != null ? [.. attributes] : [];
|
||||||
|
|
||||||
|
public FrostFsContainerId ContainerId { get; } = containerId;
|
||||||
|
|
||||||
|
public ulong PayloadLength { get; set; }
|
||||||
|
|
||||||
|
public byte[]? PayloadCheckSum { get; set; }
|
||||||
|
|
||||||
|
public FrostFsObjectType ObjectType { get; } = type;
|
||||||
|
|
||||||
|
public FrostFsOwner? OwnerId { get; internal set; } = owner;
|
||||||
|
|
||||||
|
public FrostFsVersion? Version { get; internal set; } = version;
|
||||||
|
|
||||||
|
public FrostFsSplit? Split { get; internal set; } = split;
|
||||||
|
|
||||||
|
internal Container.Container.Types.Attribute[]? GetGrpsAttributes()
|
||||||
|
{
|
||||||
|
grpsAttributes ??= Attributes?
|
||||||
|
.Select(a => new Container.Container.Types.Attribute { Key = a.Key, Value = a.Value })
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
return grpsAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Header GetHeader()
|
||||||
|
{
|
||||||
|
if (header == null)
|
||||||
|
{
|
||||||
|
var objTypeName = ObjectType switch
|
||||||
|
{
|
||||||
|
FrostFsObjectType.Regular => Object.ObjectType.Regular,
|
||||||
|
FrostFsObjectType.Lock => Object.ObjectType.Lock,
|
||||||
|
FrostFsObjectType.Tombstone => Object.ObjectType.Tombstone,
|
||||||
|
_ => throw new ArgumentException($"Unknown ObjectType. Value: '{ObjectType}'.")
|
||||||
|
};
|
||||||
|
|
||||||
|
this.header = new Header
|
||||||
|
{
|
||||||
|
OwnerId = OwnerId?.ToMessage(),
|
||||||
|
Version = Version?.ToMessage(),
|
||||||
|
ContainerId = ContainerId.ToMessage(),
|
||||||
|
ObjectType = objTypeName,
|
||||||
|
PayloadLength = PayloadLength
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var attribute in Attributes)
|
||||||
|
{
|
||||||
|
this.header.Attributes.Add(attribute.ToMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
var split = Split;
|
||||||
|
if (split != null)
|
||||||
|
{
|
||||||
|
this.header.Split = new Header.Types.Split
|
||||||
|
{
|
||||||
|
SplitId = split!.SplitId != null ? split.SplitId.GetSplitId() : null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.header;
|
||||||
|
}
|
||||||
|
}
|
28
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectId.cs
Normal file
28
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectId.cs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsObjectId(string id)
|
||||||
|
{
|
||||||
|
public string Value { get; } = id;
|
||||||
|
|
||||||
|
public static FrostFsObjectId FromHash(byte[] hash)
|
||||||
|
{
|
||||||
|
if (hash.Length != Constants.Sha256HashLength)
|
||||||
|
throw new FormatException("ObjectID must be a sha256 hash.");
|
||||||
|
|
||||||
|
return new FrostFsObjectId(Base58.Encode(hash));
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] ToHash()
|
||||||
|
{
|
||||||
|
return Base58.Decode(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
}
|
38
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsOwner.cs
Normal file
38
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsOwner.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
using FrostFS.Refs;
|
||||||
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsOwner(string id)
|
||||||
|
{
|
||||||
|
private OwnerID ownerID;
|
||||||
|
|
||||||
|
public string Value { get; } = id;
|
||||||
|
|
||||||
|
public static FrostFsOwner FromKey(ECDsa key)
|
||||||
|
{
|
||||||
|
return new FrostFsOwner(key.PublicKey().PublicKeyToAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
internal OwnerID OwnerID
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
ownerID ??= this.ToMessage();
|
||||||
|
return ownerID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] ToHash()
|
||||||
|
{
|
||||||
|
return Base58.Decode(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
}
|
24
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsSplit.cs
Normal file
24
src/FrostFS.SDK.ClientV2/Models/Object/FrostFsSplit.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsSplit(SplitId splitId)
|
||||||
|
{
|
||||||
|
public FrostFsSplit() : this(new SplitId())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SplitId SplitId { get; private set; } = splitId;
|
||||||
|
|
||||||
|
public FrostFsObjectId? Parent { get; set; }
|
||||||
|
|
||||||
|
public FrostFsObjectId? Previous { get; set; }
|
||||||
|
|
||||||
|
public FrostFsSignature? ParentSignature { get; set; }
|
||||||
|
|
||||||
|
public FrostFsObjectHeader? ParentHeader { get; set; }
|
||||||
|
|
||||||
|
public List<FrostFsObjectId> Children { get; } = [];
|
||||||
|
|
||||||
|
public Refs.Signature ParentSignatureGrpc { get; set; }
|
||||||
|
}
|
10
src/FrostFS.SDK.ClientV2/Models/Object/IObjectReader.cs
Normal file
10
src/FrostFS.SDK.ClientV2/Models/Object/IObjectReader.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public interface IObjectReader : IDisposable
|
||||||
|
{
|
||||||
|
Task<ReadOnlyMemory<byte>?> ReadChunk(CancellationToken cancellationToken = default);
|
||||||
|
}
|
62
src/FrostFS.SDK.ClientV2/Models/Object/SplitId.cs
Normal file
62
src/FrostFS.SDK.ClientV2/Models/Object/SplitId.cs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
|
||||||
|
using Google.Protobuf;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class SplitId
|
||||||
|
{
|
||||||
|
private readonly Guid id;
|
||||||
|
|
||||||
|
private ByteString? _message;
|
||||||
|
|
||||||
|
public SplitId()
|
||||||
|
{
|
||||||
|
id = Guid.NewGuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SplitId(Guid guid)
|
||||||
|
{
|
||||||
|
id = guid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SplitId(byte[] binary)
|
||||||
|
{
|
||||||
|
id = new Guid(binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SplitId(string str)
|
||||||
|
{
|
||||||
|
id = new Guid(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SplitId CreateFromBinary(byte[] binaryData)
|
||||||
|
{
|
||||||
|
return new SplitId(binaryData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SplitId CreateFromString(string stringData)
|
||||||
|
{
|
||||||
|
return new SplitId(stringData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return id.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[]? ToBinary()
|
||||||
|
{
|
||||||
|
if (id == Guid.Empty)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return id.ToBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteString? GetSplitId()
|
||||||
|
{
|
||||||
|
return _message ??= ByteString.CopyFrom(ToBinary());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsResponseStatus(FrostFsStatusCode code, string? message = null)
|
||||||
|
{
|
||||||
|
public FrostFsStatusCode Code { get; set; } = code;
|
||||||
|
public string Message { get; set; } = message ?? string.Empty;
|
||||||
|
|
||||||
|
public bool IsSuccess => Code == FrostFsStatusCode.Success;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Response status: {Code}. Message: {Message}.";
|
||||||
|
}
|
||||||
|
}
|
10
src/FrostFS.SDK.ClientV2/Models/Response/FrostFsSignature.cs
Normal file
10
src/FrostFS.SDK.ClientV2/Models/Response/FrostFsSignature.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsSignature
|
||||||
|
{
|
||||||
|
public byte[]? Key { get; set; }
|
||||||
|
|
||||||
|
public byte[]? Sign { get; set; }
|
||||||
|
|
||||||
|
public SignatureScheme Scheme { get; set; }
|
||||||
|
}
|
20
src/FrostFS.SDK.ClientV2/Models/Response/MetaHeader.cs
Normal file
20
src/FrostFS.SDK.ClientV2/Models/Response/MetaHeader.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class MetaHeader(FrostFsVersion version, int epoch, int ttl)
|
||||||
|
{
|
||||||
|
public FrostFsVersion Version { get; set; } = version;
|
||||||
|
public int Epoch { get; set; } = epoch;
|
||||||
|
public int Ttl { get; set; } = ttl;
|
||||||
|
|
||||||
|
public static MetaHeader Default()
|
||||||
|
{
|
||||||
|
return new MetaHeader(
|
||||||
|
new FrostFsVersion(
|
||||||
|
major: 2,
|
||||||
|
minor: 13
|
||||||
|
),
|
||||||
|
epoch: 0,
|
||||||
|
ttl: 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsSessionToken(byte[] token)
|
||||||
|
{
|
||||||
|
public byte[] Token { get; private set; } = token;
|
||||||
|
}
|
|
@ -2,9 +2,11 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using FrostFS.SDK.Cryptography;
|
using FrostFS.SDK.Cryptography;
|
||||||
|
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
|
|
||||||
using Grpc.Core.Interceptors;
|
using Grpc.Core.Interceptors;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
@ -13,13 +15,13 @@ public class Context()
|
||||||
{
|
{
|
||||||
private List<Interceptor>? interceptors;
|
private List<Interceptor>? interceptors;
|
||||||
|
|
||||||
private ByteString publicKeyCache;
|
private ByteString? publicKeyCache;
|
||||||
|
|
||||||
public ECDsa Key { get; set; }
|
public ECDsa Key { get; set; }
|
||||||
|
|
||||||
public OwnerId OwnerId { get; set; }
|
public FrostFsOwner OwnerId { get; set; }
|
||||||
|
|
||||||
public ModelsV2.Version Version { get; set; }
|
public FrostFsVersion Version { get; set; }
|
||||||
|
|
||||||
public CancellationToken CancellationToken { get; set; } = default;
|
public CancellationToken CancellationToken { get; set; } = default;
|
||||||
|
|
||||||
|
@ -35,16 +37,13 @@ public class Context()
|
||||||
set { this.interceptors = value; }
|
set { this.interceptors = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteString PublicKeyCache
|
public ByteString? GetPublicKeyCache()
|
||||||
{
|
{
|
||||||
get
|
if (publicKeyCache == null && Key != null)
|
||||||
{
|
{
|
||||||
if (publicKeyCache == null)
|
publicKeyCache = ByteString.CopyFrom(Key.PublicKey());
|
||||||
{
|
|
||||||
publicKeyCache = ByteString.CopyFrom(Key.PublicKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
return publicKeyCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return publicKeyCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
using System.Security.Cryptography;
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public class Credentials(ECDsa key, OwnerId ownerId)
|
public class Credentials(ECDsa key, FrostFsOwner ownerId)
|
||||||
{
|
{
|
||||||
public ECDsa Key { get; } = key;
|
public ECDsa Key { get; } = key;
|
||||||
|
|
||||||
public OwnerId OwnerId { get; } = ownerId;
|
public FrostFsOwner OwnerId { get; } = ownerId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public interface IContext
|
public interface IContext
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
|
|
||||||
public interface ISessionToken
|
public interface ISessionToken
|
||||||
{
|
{
|
||||||
|
@ -10,5 +8,5 @@ public interface ISessionToken
|
||||||
/// member. The session has a limited validity period, and applies to a strictly defined set of operations.
|
/// member. The session has a limited validity period, and applies to a strictly defined set of operations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>Instance of the session obtained from the server</value>
|
/// <value>Instance of the session obtained from the server</value>
|
||||||
SessionToken? SessionToken { get; set; }
|
FrostFsSessionToken? SessionToken { get; set; }
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public class PrmBase() : IContext
|
public class PrmBase() : IContext
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
public sealed class PrmContainerCreate(FrostFsContainerInfo container) : PrmBase, ISessionToken
|
||||||
|
|
||||||
public sealed class PrmContainerCreate(ModelsV2.Container container) : PrmBase, ISessionToken
|
|
||||||
{
|
{
|
||||||
public ModelsV2.Container Container { get; set; } = container;
|
public FrostFsContainerInfo Container { get; set; } = container;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Since the container becomes available with some delay, it needs to poll the container status
|
/// Since the container becomes available with some delay, it needs to poll the container status
|
||||||
|
@ -16,5 +13,5 @@ public sealed class PrmContainerCreate(ModelsV2.Container container) : PrmBase,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Blank session token
|
/// Blank session token
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SessionToken? SessionToken { get; set; }
|
public FrostFsSessionToken? SessionToken { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
public sealed class PrmContainerDelete(FrostFsContainerId containerId) : PrmBase, ISessionToken
|
||||||
|
|
||||||
public sealed class PrmContainerDelete(ContainerId containerId) : PrmBase, ISessionToken
|
|
||||||
{
|
{
|
||||||
public ContainerId ContainerId { get; set; } = containerId;
|
public FrostFsContainerId ContainerId { get; set; } = containerId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Since the container is removed with some delay, it needs to poll the container status
|
/// Since the container is removed with some delay, it needs to poll the container status
|
||||||
|
@ -12,5 +10,5 @@ public sealed class PrmContainerDelete(ContainerId containerId) : PrmBase, ISess
|
||||||
/// <value>Rules for polling the result</value>
|
/// <value>Rules for polling the result</value>
|
||||||
public PrmWait? WaitParams { get; set; }
|
public PrmWait? WaitParams { get; set; }
|
||||||
|
|
||||||
public SessionToken? SessionToken { get; set; }
|
public FrostFsSessionToken? SessionToken { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
public sealed class PrmContainerGet(FrostFsContainerId container) : PrmBase
|
||||||
|
|
||||||
public sealed class PrmContainerGet(ContainerId containerId) : PrmBase
|
|
||||||
{
|
{
|
||||||
public ContainerId ContainerId { get; set; } = containerId;
|
public FrostFsContainerId Container { get; set; } = container;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public sealed class PrmContainerGetAll() : PrmBase()
|
public sealed class PrmContainerGetAll() : PrmBase()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public sealed class PrmNetmapSnapshot() : PrmBase
|
public sealed class PrmNetmapSnapshot() : PrmBase
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public sealed class PrmNetworkSettings() : PrmBase
|
public sealed class PrmNetworkSettings() : PrmBase
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public sealed class PrmNodeInfo() : PrmBase
|
public sealed class PrmNodeInfo() : PrmBase
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
public sealed class PrmObjectDelete(FrostFsContainerId containerId, FrostFsObjectId objectId) : PrmBase, ISessionToken
|
||||||
|
|
||||||
public sealed class PrmObjectDelete(ContainerId containerId, ObjectId objectId) : PrmBase, ISessionToken
|
|
||||||
{
|
{
|
||||||
public ContainerId ContainerId { get; set; } = containerId;
|
public FrostFsContainerId ContainerId { get; set; } = containerId;
|
||||||
|
|
||||||
public ObjectId ObjectId { get; set; } = objectId;
|
public FrostFsObjectId ObjectId { get; set; } = objectId;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public SessionToken? SessionToken { get; set; }
|
public FrostFsSessionToken? SessionToken { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
public sealed class PrmObjectGet(FrostFsContainerId containerId, FrostFsObjectId objectId) : PrmBase, ISessionToken
|
||||||
|
|
||||||
public sealed class PrmObjectGet(ContainerId containerId, ObjectId objectId) : PrmBase, ISessionToken
|
|
||||||
{
|
{
|
||||||
public ContainerId ContainerId { get; set; } = containerId;
|
public FrostFsContainerId ContainerId { get; set; } = containerId;
|
||||||
|
|
||||||
public ObjectId ObjectId { get; set; } = objectId;
|
public FrostFsObjectId ObjectId { get; set; } = objectId;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public SessionToken? SessionToken { get; set; }
|
public FrostFsSessionToken? SessionToken { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
public sealed class PrmObjectHeadGet(FrostFsContainerId containerId, FrostFsObjectId objectId) : PrmBase, ISessionToken
|
||||||
|
|
||||||
public sealed class PrmObjectHeadGet(ContainerId containerId, ObjectId objectId) : PrmBase, ISessionToken
|
|
||||||
{
|
{
|
||||||
public ContainerId ContainerId { get; set; } = containerId;
|
public FrostFsContainerId ContainerId { get; set; } = containerId;
|
||||||
|
|
||||||
public ObjectId ObjectId { get; set; } = objectId;
|
public FrostFsObjectId ObjectId { get; set; } = objectId;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public SessionToken? SessionToken { get; set; }
|
public FrostFsSessionToken? SessionToken { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public sealed class PrmObjectPut : PrmBase, ISessionToken
|
public sealed class PrmObjectPut : PrmBase, ISessionToken
|
||||||
{
|
{
|
||||||
|
@ -10,7 +9,7 @@ public sealed class PrmObjectPut : PrmBase, ISessionToken
|
||||||
/// Optional parameters ike <c>Attributes</c> can be provided as well.
|
/// Optional parameters ike <c>Attributes</c> can be provided as well.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>Header with required parameters to create an object</value>
|
/// <value>Header with required parameters to create an object</value>
|
||||||
public ObjectHeader? Header { get; set; }
|
public FrostFsObjectHeader? Header { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A stream with source data
|
/// A stream with source data
|
||||||
|
@ -37,7 +36,7 @@ public sealed class PrmObjectPut : PrmBase, ISessionToken
|
||||||
public byte[]? CustomBuffer { get; set; }
|
public byte[]? CustomBuffer { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public SessionToken? SessionToken { get; set; }
|
public FrostFsSessionToken? SessionToken { get; set; }
|
||||||
|
|
||||||
internal int MaxObjectSizeCache { get; set; }
|
internal int MaxObjectSizeCache { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
|
|
||||||
public sealed class PrmObjectSearch(ContainerId containerId, params IObjectFilter[] filters) : PrmBase, ISessionToken
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
|
public sealed class PrmObjectSearch(FrostFsContainerId containerId, params IObjectFilter[] filters) : PrmBase, ISessionToken
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines container for the search
|
/// Defines container for the search
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value></value>
|
/// <value></value>
|
||||||
public ContainerId ContainerId { get; set; } = containerId;
|
public FrostFsContainerId ContainerId { get; set; } = containerId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the search criteria
|
/// Defines the search criteria
|
||||||
|
@ -17,5 +17,5 @@ public sealed class PrmObjectSearch(ContainerId containerId, params IObjectFilte
|
||||||
public IEnumerable<IObjectFilter> Filters { get; set; } = filters;
|
public IEnumerable<IObjectFilter> Filters { get; set; } = filters;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public SessionToken? SessionToken { get; set; }
|
public FrostFsSessionToken? SessionToken { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public sealed class PrmSessionCreate(ulong expiration) : PrmBase
|
public sealed class PrmSessionCreate(ulong expiration) : PrmBase
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
|
|
||||||
public sealed class PrmSingleObjectPut(FrostFsObject frostFsObject) : PrmBase, ISessionToken
|
public sealed class PrmSingleObjectPut(FrostFsObject frostFsObject) : PrmBase, ISessionToken
|
||||||
{
|
{
|
||||||
public FrostFsObject FrostFsObject { get; set; } = frostFsObject;
|
public FrostFsObject FrostFsObject { get; set; } = frostFsObject;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public SessionToken? SessionToken { get; set; }
|
public FrostFsSessionToken? SessionToken { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public class PrmWait(TimeSpan timeout, TimeSpan pollInterval)
|
public class PrmWait(TimeSpan timeout, TimeSpan pollInterval)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,12 +3,11 @@ using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
using FrostFS.SDK.ClientV2;
|
||||||
using FrostFS.Container;
|
using FrostFS.Container;
|
||||||
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.SDK.ClientV2;
|
||||||
using FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
using FrostFS.Refs;
|
using FrostFS.Refs;
|
||||||
using FrostFS.Session;
|
using FrostFS.Session;
|
||||||
|
|
||||||
|
@ -18,14 +17,14 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
||||||
{
|
{
|
||||||
readonly SessionProvider sessions = new(context);
|
readonly SessionProvider sessions = new(context);
|
||||||
|
|
||||||
public async ValueTask<Session.SessionToken> GetOrCreateSession(ISessionToken args, Context ctx)
|
public async ValueTask<SessionToken> GetOrCreateSession(ISessionToken args, Context ctx)
|
||||||
{
|
{
|
||||||
return await sessions.GetOrCreateSession(args, ctx);
|
return await sessions.GetOrCreateSession(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<ModelsV2.Container> GetContainerAsync(PrmContainerGet args)
|
internal async Task<FrostFsContainerInfo> GetContainerAsync(PrmContainerGet args)
|
||||||
{
|
{
|
||||||
GetRequest request = GetContainerRequest(args.ContainerId.ToMessage(), args.XHeaders, args.Context!);
|
GetRequest request = GetContainerRequest(args.Container.ContainerID, args.XHeaders, args.Context!);
|
||||||
|
|
||||||
var response = await service.GetAsync(request, null, args.Context!.Deadline, args.Context.CancellationToken);
|
var response = await service.GetAsync(request, null, args.Context!.Deadline, args.Context.CancellationToken);
|
||||||
|
|
||||||
|
@ -34,13 +33,13 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
||||||
return response.Body.Container.ToModel();
|
return response.Body.Container.ToModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async IAsyncEnumerable<ContainerId> ListContainersAsync(PrmContainerGetAll args)
|
internal async IAsyncEnumerable<FrostFsContainerId> ListContainersAsync(PrmContainerGetAll args)
|
||||||
{
|
{
|
||||||
var ctx = args.Context!;
|
var ctx = args.Context!;
|
||||||
|
|
||||||
var request = new ListRequest
|
var request = new ListRequest
|
||||||
{
|
{
|
||||||
Body = new ListRequest.Types.Body
|
Body = new ()
|
||||||
{
|
{
|
||||||
OwnerId = ctx.OwnerId.ToMessage()
|
OwnerId = ctx.OwnerId.ToMessage()
|
||||||
}
|
}
|
||||||
|
@ -55,16 +54,18 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
||||||
|
|
||||||
foreach (var cid in response.Body.ContainerIds)
|
foreach (var cid in response.Body.ContainerIds)
|
||||||
{
|
{
|
||||||
yield return new ContainerId(Base58.Encode(cid.Value.ToByteArray()));
|
yield return new FrostFsContainerId(Base58.Encode(cid.Value.ToByteArray()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<ContainerId> CreateContainerAsync(PrmContainerCreate args)
|
internal async Task<FrostFsContainerId> CreateContainerAsync(PrmContainerCreate args)
|
||||||
{
|
{
|
||||||
var ctx = args.Context!;
|
var ctx = args.Context!;
|
||||||
var grpcContainer = args.Container.ToMessage();
|
|
||||||
grpcContainer.OwnerId = ctx.OwnerId.ToMessage();
|
var grpcContainer = args.Container.GetContainer();
|
||||||
grpcContainer.Version = ctx.Version.ToMessage();
|
|
||||||
|
grpcContainer.OwnerId ??= ctx.OwnerId.ToMessage();
|
||||||
|
grpcContainer.Version ??= ctx.Version.ToMessage();
|
||||||
|
|
||||||
var request = new PutRequest
|
var request = new PutRequest
|
||||||
{
|
{
|
||||||
|
@ -81,9 +82,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
||||||
null,
|
null,
|
||||||
ContainerSessionContext.Types.Verb.Put,
|
ContainerSessionContext.Types.Verb.Put,
|
||||||
ctx.Key,
|
ctx.Key,
|
||||||
ctx.PublicKeyCache);
|
ctx.GetPublicKeyCache());
|
||||||
|
|
||||||
var v = sessionToken.Body.OwnerId == grpcContainer.OwnerId;
|
|
||||||
|
|
||||||
request.AddMetaHeader(args.XHeaders, sessionToken);
|
request.AddMetaHeader(args.XHeaders, sessionToken);
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
||||||
|
|
||||||
await WaitForContainer(WaitExpects.Exists, response.Body.ContainerId, args.WaitParams, ctx);
|
await WaitForContainer(WaitExpects.Exists, response.Body.ContainerId, args.WaitParams, ctx);
|
||||||
|
|
||||||
return new ContainerId(Base58.Encode(response.Body.ContainerId.Value.ToByteArray()));
|
return new FrostFsContainerId(response.Body.ContainerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task DeleteContainerAsync(PrmContainerDelete args)
|
internal async Task DeleteContainerAsync(PrmContainerDelete args)
|
||||||
|
@ -116,7 +115,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
||||||
request.Body.ContainerId,
|
request.Body.ContainerId,
|
||||||
ContainerSessionContext.Types.Verb.Delete,
|
ContainerSessionContext.Types.Verb.Delete,
|
||||||
ctx.Key,
|
ctx.Key,
|
||||||
ctx.PublicKeyCache);
|
ctx.GetPublicKeyCache());
|
||||||
|
|
||||||
request.AddMetaHeader(args.XHeaders, sessionToken);
|
request.AddMetaHeader(args.XHeaders, sessionToken);
|
||||||
|
|
||||||
|
@ -193,7 +192,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
||||||
if (DateTime.UtcNow >= deadLine)
|
if (DateTime.UtcNow >= deadLine)
|
||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
|
|
||||||
if (ex.Status.Code != ModelsV2.Enums.StatusCode.ContainerNotFound)
|
if (ex.Status.Code != FrostFsStatusCode.ContainerNotFound)
|
||||||
throw;
|
throw;
|
||||||
|
|
||||||
if (expect == WaitExpects.Removed)
|
if (expect == WaitExpects.Removed)
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FrostFS.Netmap;
|
|
||||||
using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
|
||||||
using NodeInfo = FrostFS.SDK.ModelsV2.Netmap.NodeInfo;
|
|
||||||
|
|
||||||
using FrostFS.SDK.ModelsV2.Netmap;
|
using FrostFS.Netmap;
|
||||||
|
using FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
using static FrostFS.Netmap.NetworkConfig.Types;
|
using static FrostFS.Netmap.NetworkConfig.Types;
|
||||||
using FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
|
@ -40,7 +38,7 @@ internal class NetmapServiceProvider : ContextAccessor
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<NodeInfo> GetLocalNodeInfoAsync(PrmNodeInfo args)
|
internal async Task<FrostFsNodeInfo> GetLocalNodeInfoAsync(PrmNodeInfo args)
|
||||||
{
|
{
|
||||||
var ctx = args.Context!;
|
var ctx = args.Context!;
|
||||||
var request = new LocalNodeInfoRequest
|
var request = new LocalNodeInfoRequest
|
||||||
|
@ -72,7 +70,7 @@ internal class NetmapServiceProvider : ContextAccessor
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<NetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot args)
|
internal async Task<FrostFsNetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot args)
|
||||||
{
|
{
|
||||||
var ctx = args.Context!;
|
var ctx = args.Context!;
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Google.Protobuf;
|
|
||||||
|
|
||||||
using FrostFS.Object;
|
using FrostFS.Object;
|
||||||
using FrostFS.Refs;
|
using FrostFS.Refs;
|
||||||
|
using FrostFS.SDK.ClientV2.Extensions;
|
||||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
using FrostFS.SDK.ClientV2;
|
||||||
using FrostFS.SDK.Cryptography;
|
using FrostFS.SDK.Cryptography;
|
||||||
using FrostFS.Session;
|
using FrostFS.Session;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using FrostFS.SDK.ClientV2.Extensions;
|
using Google.Protobuf;
|
||||||
using FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
using System.Buffers;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, ClientEnvironment env) : ContextAccessor(env), ISessionProvider
|
internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, ClientEnvironment env)
|
||||||
|
: ContextAccessor(env), ISessionProvider
|
||||||
{
|
{
|
||||||
readonly SessionProvider sessions = new (env);
|
readonly SessionProvider sessions = new (env);
|
||||||
|
|
||||||
|
@ -26,16 +26,17 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
return await sessions.GetOrCreateSession(args, ctx);
|
return await sessions.GetOrCreateSession(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<ObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args)
|
internal async Task<FrostFsObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args)
|
||||||
{
|
{
|
||||||
var ctx = args.Context!;
|
var ctx = args.Context!;
|
||||||
|
|
||||||
var request = new HeadRequest
|
var request = new HeadRequest
|
||||||
{
|
{
|
||||||
Body = new HeadRequest.Types.Body
|
Body = new HeadRequest.Types.Body
|
||||||
{
|
{
|
||||||
Address = new Address
|
Address = new Address
|
||||||
{
|
{
|
||||||
ContainerId = args.ContainerId.ToMessage(),
|
ContainerId = args.ContainerId.ContainerID,
|
||||||
ObjectId = args.ObjectId.ToMessage()
|
ObjectId = args.ObjectId.ToMessage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +120,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
Verifier.CheckResponse(response);
|
Verifier.CheckResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async IAsyncEnumerable<ObjectId> SearchObjectsAsync(PrmObjectSearch args)
|
internal async IAsyncEnumerable<FrostFsObjectId> SearchObjectsAsync(PrmObjectSearch args)
|
||||||
{
|
{
|
||||||
var ctx = args.Context!;
|
var ctx = args.Context!;
|
||||||
var request = new SearchRequest
|
var request = new SearchRequest
|
||||||
|
@ -149,11 +150,11 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
|
|
||||||
await foreach (var oid in objectsIds)
|
await foreach (var oid in objectsIds)
|
||||||
{
|
{
|
||||||
yield return ObjectId.FromHash(oid.Value.ToByteArray());
|
yield return FrostFsObjectId.FromHash(oid.Value.ToByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<ObjectId> PutObjectAsync(PrmObjectPut args)
|
internal async Task<FrostFsObjectId> PutObjectAsync(PrmObjectPut args)
|
||||||
{
|
{
|
||||||
if (args.Header == null)
|
if (args.Header == null)
|
||||||
throw new ArgumentException("Value cannot be null", nameof(args.Header));
|
throw new ArgumentException("Value cannot be null", nameof(args.Header));
|
||||||
|
@ -174,17 +175,14 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<ObjectId> PutSingleObjectAsync(PrmSingleObjectPut args)
|
internal async Task<FrostFsObjectId> PutSingleObjectAsync(PrmSingleObjectPut args)
|
||||||
{
|
{
|
||||||
var ctx = args.Context!;
|
var ctx = args.Context!;
|
||||||
var grpcObject = ObjectTools.CreateObject(args.FrostFsObject, ctx);
|
var grpcObject = ObjectTools.CreateObject(args.FrostFsObject, ctx);
|
||||||
|
|
||||||
var request = new PutSingleRequest
|
var request = new PutSingleRequest
|
||||||
{
|
{
|
||||||
Body = new PutSingleRequest.Types.Body()
|
Body = new () { Object = grpcObject }
|
||||||
{
|
|
||||||
Object = grpcObject
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var sessionToken = await GetOrCreateSession(args, ctx);
|
var sessionToken = await GetOrCreateSession(args, ctx);
|
||||||
|
@ -202,15 +200,15 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
|
|
||||||
Verifier.CheckResponse(response);
|
Verifier.CheckResponse(response);
|
||||||
|
|
||||||
return ObjectId.FromHash(grpcObject.ObjectId.Value.ToByteArray());
|
return FrostFsObjectId.FromHash(grpcObject.ObjectId.Value.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ObjectId> PutClientCutObject(PrmObjectPut args)
|
private async Task<FrostFsObjectId> PutClientCutObject(PrmObjectPut args)
|
||||||
{
|
{
|
||||||
var ctx = args.Context!;
|
var ctx = args.Context!;
|
||||||
|
|
||||||
var tokenRaw = await GetOrCreateSession(args, ctx);
|
var tokenRaw = await GetOrCreateSession(args, ctx);
|
||||||
var token = new ModelsV2.SessionToken(tokenRaw.Serialize());
|
var token = new FrostFsSessionToken(tokenRaw.Serialize());
|
||||||
|
|
||||||
args.SessionToken = token;
|
args.SessionToken = token;
|
||||||
|
|
||||||
|
@ -237,9 +235,9 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
var restPart = (restBytes % (ulong)objectSize) > 0 ? 1 : 0;
|
var restPart = (restBytes % (ulong)objectSize) > 0 ? 1 : 0;
|
||||||
var objectsCount = fullLength > 0 ? (int)(restBytes / (ulong)objectSize) + restPart : 0;
|
var objectsCount = fullLength > 0 ? (int)(restBytes / (ulong)objectSize) + restPart : 0;
|
||||||
|
|
||||||
List<ObjectId> sentObjectIds = new(objectsCount);
|
List<FrostFsObjectId> sentObjectIds = new(objectsCount);
|
||||||
|
|
||||||
Split? split = null;
|
FrostFsSplit? split = null;
|
||||||
|
|
||||||
// keep attributes for the large object
|
// keep attributes for the large object
|
||||||
var attributes = args.Header!.Attributes;
|
var attributes = args.Header!.Attributes;
|
||||||
|
@ -249,7 +247,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
{
|
{
|
||||||
if (split == null)
|
if (split == null)
|
||||||
{
|
{
|
||||||
split = new Split();
|
split = new FrostFsSplit();
|
||||||
args.Header!.Attributes = [];
|
args.Header!.Attributes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +264,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
// send the last part and create linkObject
|
// send the last part and create linkObject
|
||||||
if (sentObjectIds.Count > 0)
|
if (sentObjectIds.Count > 0)
|
||||||
{
|
{
|
||||||
var largeObjectHeader = new ObjectHeader(header.ContainerId) { PayloadLength = fullLength };
|
var largeObjectHeader = new FrostFsObjectHeader(header.ContainerId) { PayloadLength = fullLength };
|
||||||
|
|
||||||
largeObjectHeader.Attributes.AddRange(attributes);
|
largeObjectHeader.Attributes.AddRange(attributes);
|
||||||
|
|
||||||
|
@ -276,7 +274,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
|
|
||||||
sentObjectIds.Add(result.ObjectId);
|
sentObjectIds.Add(result.ObjectId);
|
||||||
|
|
||||||
var linkObject = new LinkObject(header.ContainerId, split!.SplitId, largeObjectHeader)
|
var linkObject = new FrostFsLinkObject(header.ContainerId, split!.SplitId, largeObjectHeader)
|
||||||
.AddChildren(sentObjectIds);
|
.AddChildren(sentObjectIds);
|
||||||
|
|
||||||
_ = await PutSingleObjectAsync(new PrmSingleObjectPut(linkObject) { Context = args.Context});
|
_ = await PutSingleObjectAsync(new PrmSingleObjectPut(linkObject) { Context = args.Context});
|
||||||
|
@ -290,9 +288,9 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
return singlePartResult.ObjectId;
|
return singlePartResult.ObjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PutObjectResult(ObjectId objectId, int objectSize)
|
struct PutObjectResult(FrostFsObjectId objectId, int objectSize)
|
||||||
{
|
{
|
||||||
public ObjectId ObjectId = objectId;
|
public FrostFsObjectId ObjectId = objectId;
|
||||||
public int ObjectSize = objectSize;
|
public int ObjectSize = objectSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +357,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
var response = await stream.Close();
|
var response = await stream.Close();
|
||||||
Verifier.CheckResponse(response);
|
Verifier.CheckResponse(response);
|
||||||
|
|
||||||
return new PutObjectResult(ObjectId.FromHash(response.Body.ObjectId.Value.ToByteArray()), sentBytes);
|
return new PutObjectResult(FrostFsObjectId.FromHash(response.Body.ObjectId.Value.ToByteArray()), sentBytes);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -374,10 +372,10 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
||||||
{
|
{
|
||||||
var header = args.Header!;
|
var header = args.Header!;
|
||||||
|
|
||||||
header.OwnerId = ctx.OwnerId;
|
header.OwnerId ??= ctx.OwnerId;
|
||||||
header.Version = ctx.Version;
|
header.Version ??= ctx.Version;
|
||||||
|
|
||||||
var grpcHeader = header.ToMessage();
|
var grpcHeader = header.GetHeader();
|
||||||
|
|
||||||
if (header.Split != null)
|
if (header.Split != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
using FrostFS.SDK.ClientV2.Parameters;
|
using FrostFS.SDK.ClientV2;
|
||||||
using FrostFS.Session;
|
using FrostFS.Session;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
|
@ -4,5 +4,3 @@ internal class ContextAccessor(ClientEnvironment context)
|
||||||
{
|
{
|
||||||
protected ClientEnvironment Context { get; set; } = context;
|
protected ClientEnvironment Context { get; set; } = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FrostFS.SDK.ClientV2.Parameters;
|
|
||||||
|
using FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using Grpc.Net.Client;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
using Grpc.Net.Client;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public class ClientEnvironment(Client client, ECDsa? key, OwnerId? owner, GrpcChannel channel, ModelsV2.Version version) : IDisposable
|
public class ClientEnvironment(Client client, ECDsa? key, FrostFsOwner? owner, GrpcChannel channel, FrostFsVersion version) : IDisposable
|
||||||
{
|
{
|
||||||
private ArrayPool<byte> _arrayPool;
|
private ArrayPool<byte> _arrayPool;
|
||||||
|
|
||||||
internal OwnerId? Owner { get; } = owner;
|
internal FrostFsOwner? Owner { get; } = owner;
|
||||||
|
|
||||||
internal GrpcChannel Channel { get; private set; } = channel;
|
internal GrpcChannel Channel { get; private set; } = channel;
|
||||||
|
|
||||||
internal ModelsV2.Version Version { get; } = version;
|
internal FrostFsVersion Version { get; } = version;
|
||||||
|
|
||||||
internal NetworkSettings? NetworkSettings { get; set; }
|
internal NetworkSettings? NetworkSettings { get; set; }
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class ClientEnvironment(Client client, ECDsa? key, OwnerId? owner, GrpcCh
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
Channel.Dispose();
|
Channel?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2.Extensions;
|
namespace FrostFS.SDK.ClientV2.Extensions;
|
||||||
|
|
||||||
|
@ -21,29 +19,29 @@ public static class ObjectExtensions
|
||||||
|
|
||||||
public static FrostFsObject AddAttribute(this FrostFsObject obj, string key, string value)
|
public static FrostFsObject AddAttribute(this FrostFsObject obj, string key, string value)
|
||||||
{
|
{
|
||||||
obj.AddAttribute(new ObjectAttribute(key, value));
|
obj.AddAttribute(new FrostFsAttribute(key, value));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FrostFsObject AddAttribute(this FrostFsObject obj, ObjectAttribute attribute)
|
public static FrostFsObject AddAttribute(this FrostFsObject obj, FrostFsAttribute attribute)
|
||||||
{
|
{
|
||||||
obj.Header.Attributes.Add(attribute);
|
obj.Header.Attributes.Add(attribute);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FrostFsObject AddAttributes(this FrostFsObject obj, IEnumerable<ObjectAttribute> attributes)
|
public static FrostFsObject AddAttributes(this FrostFsObject obj, IEnumerable<FrostFsAttribute> attributes)
|
||||||
{
|
{
|
||||||
obj.Header.Attributes.AddRange(attributes);
|
obj.Header.Attributes.AddRange(attributes);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FrostFsObject SetSplit(this FrostFsObject obj, Split? split)
|
public static FrostFsObject SetSplit(this FrostFsObject obj, FrostFsSplit? split)
|
||||||
{
|
{
|
||||||
obj.Header.Split = split;
|
obj.Header.Split = split;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LinkObject AddChildren(this LinkObject linkObject, IEnumerable<ObjectId> objectIds)
|
public static FrostFsLinkObject AddChildren(this FrostFsLinkObject linkObject, IEnumerable<FrostFsObjectId> objectIds)
|
||||||
{
|
{
|
||||||
linkObject.Header.Split!.Children.AddRange(objectIds);
|
linkObject.Header.Split!.Children.AddRange(objectIds);
|
||||||
return linkObject;
|
return linkObject;
|
||||||
|
|
|
@ -4,7 +4,6 @@ using System.Threading.Tasks;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
|
|
||||||
using FrostFS.Object;
|
using FrostFS.Object;
|
||||||
using FrostFS.SDK.ModelsV2;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
@ -33,7 +32,7 @@ public class ObjectReader(AsyncServerStreamingCall<GetResponse> call) : IObjectR
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<byte[]?> ReadChunk(CancellationToken cancellationToken = default)
|
public async Task<ReadOnlyMemory<byte>?> ReadChunk(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (!await Call.ResponseStream.MoveNext(cancellationToken))
|
if (!await Call.ResponseStream.MoveNext(cancellationToken))
|
||||||
return null;
|
return null;
|
||||||
|
@ -44,14 +43,14 @@ public class ObjectReader(AsyncServerStreamingCall<GetResponse> call) : IObjectR
|
||||||
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Chunk)
|
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Chunk)
|
||||||
throw new InvalidOperationException("unexpected message type");
|
throw new InvalidOperationException("unexpected message type");
|
||||||
|
|
||||||
return response.Body.Chunk.ToByteArray();
|
return response.Body.Chunk.Memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (!disposed)
|
if (!disposed)
|
||||||
{
|
{
|
||||||
Call.Dispose();
|
Call?.Dispose();
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
disposed = true;
|
disposed = true;
|
||||||
|
|
|
@ -30,6 +30,6 @@ internal class ObjectStreamer(AsyncClientStreamingCall<PutRequest, PutResponse>
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Call.Dispose();
|
Call?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,12 @@ 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;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
internal class ObjectTools
|
internal class ObjectTools
|
||||||
{
|
{
|
||||||
internal static ObjectId CalculateObjectId(ObjectHeader header, Context ctx)
|
internal static FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx)
|
||||||
{
|
{
|
||||||
var grpcHeader = CreateHeader(header, [], ctx);
|
var grpcHeader = CreateHeader(header, [], ctx);
|
||||||
|
|
||||||
|
@ -24,10 +23,10 @@ internal class ObjectTools
|
||||||
|
|
||||||
internal static Object.Object CreateObject(FrostFsObject @object, Context ctx)
|
internal static Object.Object CreateObject(FrostFsObject @object, Context ctx)
|
||||||
{
|
{
|
||||||
@object.Header.OwnerId = ctx.OwnerId;
|
@object.Header.OwnerId ??= ctx.OwnerId;
|
||||||
@object.Header.Version = ctx.Version;
|
@object.Header.Version ??= ctx.Version;
|
||||||
|
|
||||||
var grpcHeader = @object.Header.ToMessage();
|
var grpcHeader = @object.Header.GetHeader();
|
||||||
|
|
||||||
grpcHeader.PayloadLength = (ulong)@object.Payload.Length;
|
grpcHeader.PayloadLength = (ulong)@object.Payload.Length;
|
||||||
grpcHeader.PayloadHash = Sha256Checksum(@object.Payload);
|
grpcHeader.PayloadHash = Sha256Checksum(@object.Payload);
|
||||||
|
@ -47,18 +46,21 @@ internal class ObjectTools
|
||||||
|
|
||||||
obj.Signature = new Refs.Signature
|
obj.Signature = new Refs.Signature
|
||||||
{
|
{
|
||||||
Key = ctx.PublicKeyCache,
|
Key = ctx.GetPublicKeyCache(),
|
||||||
Sign = ByteString.CopyFrom(ctx.Key.SignData(obj.ObjectId.ToByteArray())),
|
Sign = ByteString.CopyFrom(ctx.Key.SignData(obj.ObjectId.ToByteArray())),
|
||||||
};
|
};
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetSplitValues(Header grpcHeader, ModelsV2.Split split, Context ctx)
|
internal static void SetSplitValues(Header grpcHeader, FrostFsSplit split, Context ctx)
|
||||||
{
|
{
|
||||||
|
if (split == null)
|
||||||
|
return;
|
||||||
|
|
||||||
grpcHeader.Split = new Header.Types.Split
|
grpcHeader.Split = new Header.Types.Split
|
||||||
{
|
{
|
||||||
SplitId = split.SplitId != null ? ByteString.CopyFrom(split.SplitId.ToBinary()) : null
|
SplitId = split.SplitId?.GetSplitId()
|
||||||
};
|
};
|
||||||
|
|
||||||
if (split.Children != null && split.Children.Count != 0)
|
if (split.Children != null && split.Children.Count != 0)
|
||||||
|
@ -72,7 +74,7 @@ internal class ObjectTools
|
||||||
grpcHeader.Split.ParentHeader = grpcParentHeader;
|
grpcHeader.Split.ParentHeader = grpcParentHeader;
|
||||||
grpcHeader.Split.ParentSignature = new Refs.Signature
|
grpcHeader.Split.ParentSignature = new Refs.Signature
|
||||||
{
|
{
|
||||||
Key = ctx.PublicKeyCache,
|
Key = ctx.GetPublicKeyCache(),
|
||||||
Sign = ByteString.CopyFrom(ctx.Key.SignData(grpcHeader.Split.Parent.ToByteArray())),
|
Sign = ByteString.CopyFrom(ctx.Key.SignData(grpcHeader.Split.Parent.ToByteArray())),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,12 +84,12 @@ internal class ObjectTools
|
||||||
grpcHeader.Split.Previous = split.Previous?.ToMessage();
|
grpcHeader.Split.Previous = split.Previous?.ToMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Header CreateHeader(ObjectHeader header, byte[]? payload, Context ctx)
|
internal static Header CreateHeader(FrostFsObjectHeader header, byte[]? payload, Context ctx)
|
||||||
{
|
{
|
||||||
var grpcHeader = header.ToMessage();
|
header.OwnerId ??= ctx.OwnerId;
|
||||||
|
header.Version ??= ctx.Version;
|
||||||
|
|
||||||
grpcHeader.OwnerId = ctx.OwnerId.ToMessage();
|
var grpcHeader = header.GetHeader();
|
||||||
grpcHeader.Version = ctx.Version.ToMessage();
|
|
||||||
|
|
||||||
if (payload != null) // && payload.Length > 0
|
if (payload != null) // && payload.Length > 0
|
||||||
grpcHeader.PayloadHash = Sha256Checksum(payload);
|
grpcHeader.PayloadHash = Sha256Checksum(payload);
|
||||||
|
|
|
@ -24,9 +24,7 @@ namespace System
|
||||||
public Index(int value, bool fromEnd = false)
|
public Index(int value, bool fromEnd = false)
|
||||||
{
|
{
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
||||||
}
|
|
||||||
|
|
||||||
if (fromEnd)
|
if (fromEnd)
|
||||||
_value = ~value;
|
_value = ~value;
|
||||||
|
@ -52,9 +50,7 @@ namespace System
|
||||||
public static Index FromStart(int value)
|
public static Index FromStart(int value)
|
||||||
{
|
{
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
||||||
}
|
|
||||||
|
|
||||||
return new Index(value);
|
return new Index(value);
|
||||||
}
|
}
|
||||||
|
@ -65,9 +61,7 @@ namespace System
|
||||||
public static Index FromEnd(int value)
|
public static Index FromEnd(int value)
|
||||||
{
|
{
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
||||||
}
|
|
||||||
|
|
||||||
return new Index(~value);
|
return new Index(~value);
|
||||||
}
|
}
|
||||||
|
@ -77,14 +71,7 @@ namespace System
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_value < 0)
|
return _value < 0 ? ~_value : _value;
|
||||||
{
|
|
||||||
return ~_value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return _value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +189,7 @@ namespace System
|
||||||
{
|
{
|
||||||
int start;
|
int start;
|
||||||
var startIndex = Start;
|
var startIndex = Start;
|
||||||
|
|
||||||
if (startIndex.IsFromEnd)
|
if (startIndex.IsFromEnd)
|
||||||
start = length - startIndex.Value;
|
start = length - startIndex.Value;
|
||||||
else
|
else
|
||||||
|
@ -209,15 +197,14 @@ namespace System
|
||||||
|
|
||||||
int end;
|
int end;
|
||||||
var endIndex = End;
|
var endIndex = End;
|
||||||
|
|
||||||
if (endIndex.IsFromEnd)
|
if (endIndex.IsFromEnd)
|
||||||
end = length - endIndex.Value;
|
end = length - endIndex.Value;
|
||||||
else
|
else
|
||||||
end = endIndex.Value;
|
end = endIndex.Value;
|
||||||
|
|
||||||
if ((uint)end > (uint)length || (uint)start > (uint)end)
|
if ((uint)end > (uint)length || (uint)start > (uint)end)
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(length));
|
throw new ArgumentOutOfRangeException(nameof(length));
|
||||||
}
|
|
||||||
|
|
||||||
return (start, end - start);
|
return (start, end - start);
|
||||||
}
|
}
|
||||||
|
@ -234,9 +221,7 @@ namespace System.Runtime.CompilerServices
|
||||||
public static T[] GetSubArray<T>(T[] array, Range range)
|
public static T[] GetSubArray<T>(T[] array, Range range)
|
||||||
{
|
{
|
||||||
if (array == null)
|
if (array == null)
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(array));
|
throw new ArgumentNullException(nameof(array));
|
||||||
}
|
|
||||||
|
|
||||||
(int offset, int length) = range.GetOffsetAndLength(array.Length);
|
(int offset, int length) = range.GetOffsetAndLength(array.Length);
|
||||||
|
|
||||||
|
@ -245,9 +230,7 @@ namespace System.Runtime.CompilerServices
|
||||||
// We know the type of the array to be exactly T[].
|
// We know the type of the array to be exactly T[].
|
||||||
|
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
{
|
|
||||||
return [];
|
return [];
|
||||||
}
|
|
||||||
|
|
||||||
var dest = new T[length];
|
var dest = new T[length];
|
||||||
Array.Copy(array, offset, dest, 0, length);
|
Array.Copy(array, offset, dest, 0, length);
|
||||||
|
|
|
@ -5,7 +5,6 @@ using System.Security.Cryptography;
|
||||||
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.SDK.ProtosV2.Interfaces;
|
using FrostFS.SDK.ProtosV2.Interfaces;
|
||||||
using FrostFS.Session;
|
using FrostFS.Session;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
using FrostFS.Refs;
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
using FrostFS.SDK.ProtosV2.Interfaces;
|
||||||
|
using FrostFS.Session;
|
||||||
|
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
|
|
||||||
using Org.BouncyCastle.Asn1.Sec;
|
using Org.BouncyCastle.Asn1.Sec;
|
||||||
|
@ -9,11 +14,6 @@ using Org.BouncyCastle.Crypto.Parameters;
|
||||||
using Org.BouncyCastle.Crypto.Signers;
|
using Org.BouncyCastle.Crypto.Signers;
|
||||||
using Org.BouncyCastle.Math;
|
using Org.BouncyCastle.Math;
|
||||||
|
|
||||||
using FrostFS.Refs;
|
|
||||||
using FrostFS.SDK.Cryptography;
|
|
||||||
using FrostFS.Session;
|
|
||||||
using FrostFS.SDK.ProtosV2.Interfaces;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public static class RequestSigner
|
public static class RequestSigner
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Grpc.Core;
|
|
||||||
|
|
||||||
using FrostFS.Object;
|
using FrostFS.Object;
|
||||||
using FrostFS.Refs;
|
using FrostFS.Refs;
|
||||||
using System.Threading;
|
|
||||||
|
using Grpc.Core;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
|
@ -29,6 +29,6 @@ internal class SearchReader(AsyncServerStreamingCall<SearchResponse> call) : IDi
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Call.Dispose();
|
Call?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
using FrostFS.Refs;
|
||||||
|
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||||
|
using FrostFS.SDK.Cryptography;
|
||||||
|
using FrostFS.SDK.ProtosV2.Interfaces;
|
||||||
|
using FrostFS.Session;
|
||||||
|
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
|
|
||||||
using Org.BouncyCastle.Asn1.Sec;
|
using Org.BouncyCastle.Asn1.Sec;
|
||||||
|
@ -9,12 +15,6 @@ using Org.BouncyCastle.Crypto.Parameters;
|
||||||
using Org.BouncyCastle.Crypto.Signers;
|
using Org.BouncyCastle.Crypto.Signers;
|
||||||
using Org.BouncyCastle.Math;
|
using Org.BouncyCastle.Math;
|
||||||
|
|
||||||
using FrostFS.Refs;
|
|
||||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
|
||||||
using FrostFS.SDK.Cryptography;
|
|
||||||
using FrostFS.Session;
|
|
||||||
using FrostFS.SDK.ProtosV2.Interfaces;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ClientV2;
|
namespace FrostFS.SDK.ClientV2;
|
||||||
|
|
||||||
public static class Verifier
|
public static class Verifier
|
||||||
|
|
|
@ -2,7 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
public class ClientSettings
|
public class ClientSettings
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
using System;
|
|
||||||
using FrostFS.SDK.ModelsV2.Enums;
|
|
||||||
using FrostFS.SDK.ModelsV2.Netmap;
|
|
||||||
|
|
||||||
namespace FrostFS.SDK.ModelsV2;
|
|
||||||
|
|
||||||
public class Container(BasicAcl basicAcl, PlacementPolicy placementPolicy)
|
|
||||||
{
|
|
||||||
public Guid Nonce { get; set; } = Guid.NewGuid();
|
|
||||||
public BasicAcl BasicAcl { get; set; } = basicAcl;
|
|
||||||
public PlacementPolicy PlacementPolicy { get; set; } = placementPolicy;
|
|
||||||
public Version? Version { get; set; }
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace FrostFS.SDK.ModelsV2;
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
public class ContainerId(string id)
|
public class ContainerId(string id)
|
||||||
{
|
{
|
||||||
|
|
11
src/FrostFS.SDK.ModelsV2/Containers/FrostFsContainer.cs
Normal file
11
src/FrostFS.SDK.ModelsV2/Containers/FrostFsContainer.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public class FrostFsContainer(BasicAcl basicAcl, FrostFsPlacementPolicy placementPolicy)
|
||||||
|
{
|
||||||
|
public Guid Nonce { get; set; } = Guid.NewGuid();
|
||||||
|
public BasicAcl BasicAcl { get; set; } = basicAcl;
|
||||||
|
public FrostFsPlacementPolicy PlacementPolicy { get; set; } = placementPolicy;
|
||||||
|
public FrostFsVersion? Version { get; set; }
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace FrostFS.SDK.ModelsV2.Enums;
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
public enum BasicAcl
|
public enum BasicAcl
|
||||||
{
|
{
|
||||||
|
|
10
src/FrostFS.SDK.ModelsV2/Enums/FrostFsObjectMatchType.cs
Normal file
10
src/FrostFS.SDK.ModelsV2/Enums/FrostFsObjectMatchType.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace FrostFS.SDK;
|
||||||
|
|
||||||
|
public enum FrostFsObjectMatchType
|
||||||
|
{
|
||||||
|
Unspecified = 0,
|
||||||
|
Equals = 1,
|
||||||
|
NotEquals = 2,
|
||||||
|
KeyAbsent = 3,
|
||||||
|
StartsWith = 4
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue