[#23] Client: Refactoring to optimize memory usage
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
|
||||
#
|
||||
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}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.Cryptography", "src\FrostFS.SDK.Cryptography\FrostFS.SDK.Cryptography.csproj", "{3D804F4A-B0B2-47A5-B006-BE447BE64B50}"
|
||||
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}"
|
||||
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
|
||||
Global
|
||||
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}.Release|Any CPU.ActiveCfg = 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.Build.0 = Debug|Any CPU
|
||||
{5012EF96-9C9E-4E77-BC78-B4111EE54107}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
157
README.md
157
README.md
|
@ -21,137 +21,62 @@ neo-go wallet export -w <path_to_your_wallet> -d <address_from_p1>
|
|||
### Container
|
||||
|
||||
```csharp
|
||||
using FrostFS.SDK;
|
||||
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 containersIds = await fsClient.ListContainersAsync();
|
||||
var Key = "KwHDAJ66o8FoLBjVbjP2sWBmgBMGjt7Vv4boA7xQrBoAYBE397Aq";
|
||||
var Host = "http://172.22.33.44:8080";
|
||||
|
||||
// Create container
|
||||
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)
|
||||
var options = Options.Create(new SingleOwnerClientSettings
|
||||
{
|
||||
List<ObjectId> sentObjectIds = [];
|
||||
FrostFS.SDK.ModelsV2.Object? currentObject;
|
||||
Key = Key,
|
||||
Host = Host
|
||||
});
|
||||
|
||||
var partSize = 1024 * 1024;
|
||||
var buffer = new byte[partSize];
|
||||
using var client = Client.GetSingleOwnerInstance(options);
|
||||
|
||||
var largeObject = new LargeObject(containerId);
|
||||
|
||||
var split = new Split();
|
||||
|
||||
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)
|
||||
await foreach (var cid in client.ListContainersAsync())
|
||||
{
|
||||
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);
|
||||
await client.DeleteContainerAsync(new PrmContainerDelete(cid));
|
||||
}
|
||||
|
||||
if (sentObjectIds.Any())
|
||||
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
|
||||
{
|
||||
largeObject.CalculateHash()
|
||||
.AddAttribute(fileNameAttribute);
|
||||
Header = new FrostFsObjectHeader(
|
||||
containerId: containerId,
|
||||
type: FrostFsObjectType.Regular,
|
||||
[new FrostFsAttribute("fileName", "test")]),
|
||||
Payload = fileStream
|
||||
};
|
||||
|
||||
currentObject.SetParent(largeObject);
|
||||
FrostFsObjectId objectId = await client.PutObjectAsync(param);
|
||||
|
||||
var objectId = await fsClient.PutSingleObjectAsync(currentObject);
|
||||
sentObjectIds.Add(objectId);
|
||||
var filter = new FilterByAttribute(FrostFsObjectMatchType.Equals, "fileName", "test");
|
||||
|
||||
var linkObject = new LinkObject(containerId, split.SplitId, largeObject)
|
||||
.AddChildren(sentObjectIds)
|
||||
.AddAttribute(fileNameAttribute);
|
||||
|
||||
_ = await fsClient.PutSingleObjectAsync(linkObject);
|
||||
|
||||
return currentObject.GetParentId();
|
||||
await foreach (var objId in client.SearchObjectsAsync(new PrmObjectSearch(containerId) { Filters = [filter] }))
|
||||
{
|
||||
var objHeader = await client.GetObjectHeadAsync(new PrmObjectHeadGet(containerId, objId));
|
||||
}
|
||||
|
||||
return await fsClient.PutSingleObjectAsync(currentObject);
|
||||
}
|
||||
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
|
||||
{
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
using FrostFS.Container;
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
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;
|
||||
|
||||
|
@ -70,14 +70,14 @@ public class Client : IFrostFSClient
|
|||
ObjectService.ObjectServiceClient objectService)
|
||||
{
|
||||
var ecdsaKey = settings.Value.Key.LoadWif();
|
||||
OwnerId.FromKey(ecdsaKey);
|
||||
FrostFsOwner.FromKey(ecdsaKey);
|
||||
|
||||
ClientCtx = new ClientEnvironment(
|
||||
client: this,
|
||||
key: ecdsaKey,
|
||||
owner: OwnerId.FromKey(ecdsaKey),
|
||||
owner: FrostFsOwner.FromKey(ecdsaKey),
|
||||
channel: InitGrpcChannel(settings.Value.Host, channelOptions),
|
||||
version: new Version(2, 13));
|
||||
version: new FrostFsVersion(2, 13));
|
||||
|
||||
ContainerServiceClient = containerService;
|
||||
NetmapServiceClient = netmapService;
|
||||
|
@ -98,7 +98,7 @@ public class Client : IFrostFSClient
|
|||
key: null,
|
||||
owner: null,
|
||||
channel: channel,
|
||||
version: new Version(2, 13));
|
||||
version: new FrostFsVersion(2, 13));
|
||||
|
||||
// TODO: define timeout logic
|
||||
// CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20) });
|
||||
|
@ -117,9 +117,9 @@ public class Client : IFrostFSClient
|
|||
ClientCtx = new ClientEnvironment(
|
||||
this,
|
||||
key: ecdsaKey,
|
||||
owner: OwnerId.FromKey(ecdsaKey),
|
||||
owner: FrostFsOwner.FromKey(ecdsaKey),
|
||||
channel: channel,
|
||||
version: new Version(2, 13));
|
||||
version: new FrostFsVersion(2, 13));
|
||||
|
||||
// TODO: define timeout logic
|
||||
CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20)});
|
||||
|
@ -135,26 +135,26 @@ public class Client : IFrostFSClient
|
|||
{
|
||||
if (disposing && !isDisposed)
|
||||
{
|
||||
ClientCtx.Dispose();
|
||||
ClientCtx?.Dispose();
|
||||
isDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#region ContainerImplementation
|
||||
public Task<ModelsV2.Container> GetContainerAsync(PrmContainerGet args)
|
||||
public Task<FrostFsContainerInfo> GetContainerAsync(PrmContainerGet args)
|
||||
{
|
||||
var service = GetContainerService(args);
|
||||
return service.GetContainerAsync(args);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<ContainerId> ListContainersAsync(PrmContainerGetAll? args = null)
|
||||
public IAsyncEnumerable<FrostFsContainerId> ListContainersAsync(PrmContainerGetAll? args = null)
|
||||
{
|
||||
args ??= new PrmContainerGetAll();
|
||||
var service = GetContainerService(args);
|
||||
return service.ListContainersAsync(args);
|
||||
}
|
||||
|
||||
public Task<ContainerId> CreateContainerAsync(PrmContainerCreate args)
|
||||
public Task<FrostFsContainerId> CreateContainerAsync(PrmContainerCreate args)
|
||||
{
|
||||
var service = GetContainerService(args);
|
||||
return service.CreateContainerAsync(args);
|
||||
|
@ -168,14 +168,14 @@ public class Client : IFrostFSClient
|
|||
#endregion
|
||||
|
||||
#region NetworkImplementation
|
||||
public Task<NetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot? args)
|
||||
public Task<FrostFsNetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot? args)
|
||||
{
|
||||
args ??= new PrmNetmapSnapshot();
|
||||
var service = GetNetmapService(args);
|
||||
return service.GetNetmapSnapshotAsync(args);
|
||||
}
|
||||
|
||||
public Task<ModelsV2.Netmap.NodeInfo> GetNodeInfoAsync(PrmNodeInfo? args)
|
||||
public Task<FrostFsNodeInfo> GetNodeInfoAsync(PrmNodeInfo? args)
|
||||
{
|
||||
args ??= new PrmNodeInfo();
|
||||
var service = GetNetmapService(args);
|
||||
|
@ -191,7 +191,7 @@ public class Client : IFrostFSClient
|
|||
#endregion
|
||||
|
||||
#region ObjectImplementation
|
||||
public Task<ObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args)
|
||||
public Task<FrostFsObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args)
|
||||
{
|
||||
var service = GetObjectService(args);
|
||||
return service.GetObjectHeadAsync(args);
|
||||
|
@ -203,13 +203,13 @@ public class Client : IFrostFSClient
|
|||
return service.GetObjectAsync(args);
|
||||
}
|
||||
|
||||
public Task<ObjectId> PutObjectAsync(PrmObjectPut args)
|
||||
public Task<FrostFsObjectId> PutObjectAsync(PrmObjectPut args)
|
||||
{
|
||||
var service = GetObjectService(args);
|
||||
return service.PutObjectAsync(args);
|
||||
}
|
||||
|
||||
public Task<ObjectId> PutSingleObjectAsync(PrmSingleObjectPut args)
|
||||
public Task<FrostFsObjectId> PutSingleObjectAsync(PrmSingleObjectPut args)
|
||||
{
|
||||
var service = GetObjectService(args);
|
||||
return service.PutSingleObjectAsync(args);
|
||||
|
@ -221,7 +221,7 @@ public class Client : IFrostFSClient
|
|||
return service.DeleteObjectAsync(args);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<ObjectId> SearchObjectsAsync(PrmObjectSearch args)
|
||||
public IAsyncEnumerable<FrostFsObjectId> SearchObjectsAsync(PrmObjectSearch args)
|
||||
{
|
||||
var service = GetObjectService(args);
|
||||
return service.SearchObjectsAsync(args);
|
||||
|
@ -229,12 +229,12 @@ public class Client : IFrostFSClient
|
|||
#endregion
|
||||
|
||||
#region SessionImplementation
|
||||
public async Task<ModelsV2.SessionToken> CreateSessionAsync(PrmSessionCreate args)
|
||||
public async Task<FrostFsSessionToken> CreateSessionAsync(PrmSessionCreate args)
|
||||
{
|
||||
var session = await CreateSessionInternalAsync(args);
|
||||
var token = session.Serialize();
|
||||
|
||||
return new ModelsV2.SessionToken(token);
|
||||
return new FrostFsSessionToken(token);
|
||||
}
|
||||
|
||||
internal Task<Session.SessionToken> CreateSessionInternalAsync(PrmSessionCreate args)
|
||||
|
@ -245,7 +245,7 @@ public class Client : IFrostFSClient
|
|||
#endregion
|
||||
|
||||
#region ToolsImplementation
|
||||
public ObjectId CalculateObjectId(ObjectHeader header, Context ctx)
|
||||
public FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx)
|
||||
{
|
||||
if (header == null)
|
||||
throw new ArgumentNullException(nameof(header));
|
||||
|
@ -286,7 +286,7 @@ public class Client : IFrostFSClient
|
|||
|
||||
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)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using FrostFS.SDK.Cryptography;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
using FrostFS.SDK.Cryptography;
|
||||
|
||||
using Google.Protobuf;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
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;
|
||||
|
||||
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>
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Interceptors;
|
||||
|
||||
|
|
|
@ -1,50 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using FrostFS.SDK.ClientV2.Parameters;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
using FrostFS.SDK.ModelsV2.Netmap;
|
||||
|
||||
using FrostFS.SDK.ClientV2;
|
||||
namespace FrostFS.SDK.ClientV2.Interfaces;
|
||||
|
||||
public interface IFrostFSClient : IDisposable
|
||||
{
|
||||
#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);
|
||||
#endregion
|
||||
|
||||
#region Session
|
||||
Task<SessionToken> CreateSessionAsync(PrmSessionCreate args);
|
||||
Task<FrostFsSessionToken> CreateSessionAsync(PrmSessionCreate args);
|
||||
#endregion
|
||||
|
||||
#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);
|
||||
#endregion
|
||||
|
||||
#region Object
|
||||
Task<ObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet args);
|
||||
Task<FrostFsObjectHeader> GetObjectHeadAsync(PrmObjectHeadGet 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);
|
||||
|
||||
IAsyncEnumerable<ObjectId> SearchObjectsAsync(PrmObjectSearch args);
|
||||
IAsyncEnumerable<FrostFsObjectId> SearchObjectsAsync(PrmObjectSearch args);
|
||||
#endregion
|
||||
|
||||
#region Tools
|
||||
ObjectId CalculateObjectId(ObjectHeader header, Context ctx);
|
||||
FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx);
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -1,36 +1,24 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.SDK.ModelsV2.Enums;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
public static class ContainerMapper
|
||||
{
|
||||
public static Container.Container ToMessage(this ModelsV2.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)
|
||||
public static FrostFsContainerInfo ToModel(this Container.Container container)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(BasicAcl),(int)container.BasicAcl))
|
||||
throw new ArgumentException($"Unknown BasicACL rule. Value: '{container.BasicAcl}'.");
|
||||
|
||||
BasicAcl acl = (BasicAcl)container.BasicAcl;
|
||||
|
||||
return new ModelsV2.Container(acl, container.PlacementPolicy.ToModel())
|
||||
{
|
||||
Nonce = container.Nonce.ToUuid(),
|
||||
Version = container.Version.ToModel()
|
||||
};
|
||||
return new FrostFsContainerInfo(acl,
|
||||
container.PlacementPolicy.ToModel(),
|
||||
container.Attributes?.Select(a => new FrostFsAttribute(a.Key, a.Value)).ToList(),
|
||||
container.Version?.ToModel(),
|
||||
container.OwnerId?.ToModel(),
|
||||
container.Nonce?.ToUuid());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
|
||||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using System;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
|
@ -13,16 +15,19 @@ public static class ContainerIdMapper
|
|||
.SetSlidingExpiration(TimeSpan.FromHours(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
|
||||
{
|
||||
Value = ByteString.CopyFrom(Base58.Decode(model.Value))
|
||||
};
|
||||
|
||||
Cache.Containers.Set(model, message, _oneHourExpiration);
|
||||
Cache.Containers.Set(model.Value, message, _oneHourExpiration);
|
||||
}
|
||||
|
||||
return message!;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using FrostFS.SDK.ModelsV2;
|
||||
using FrostFS.Session;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
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 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.Nodes
|
||||
.Select(n => n.ToModel(netmap.MetaHeader.Version))
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
using System;
|
||||
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 NodeInfo ToModel(this LocalNodeInfoResponse.Types.Body node)
|
||||
public static FrostFsNodeInfo ToModel(this LocalNodeInfoResponse.Types.Body node)
|
||||
{
|
||||
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
|
||||
{
|
||||
FrostFS.Netmap.NodeInfo.Types.State.Unspecified => NodeState.Unspecified,
|
||||
FrostFS.Netmap.NodeInfo.Types.State.Online => NodeState.Online,
|
||||
FrostFS.Netmap.NodeInfo.Types.State.Offline => NodeState.Offline,
|
||||
FrostFS.Netmap.NodeInfo.Types.State.Maintenance => NodeState.Maintenance,
|
||||
NodeInfo.Types.State.Unspecified => NodeState.Unspecified,
|
||||
NodeInfo.Types.State.Online => NodeState.Online,
|
||||
NodeInfo.Types.State.Offline => NodeState.Offline,
|
||||
NodeInfo.Types.State.Maintenance => NodeState.Maintenance,
|
||||
_ => throw new ArgumentException($"Unknown NodeState. Value: '{nodeInfo.State}'.")
|
||||
};
|
||||
|
||||
return new NodeInfo(
|
||||
return new FrostFsNodeInfo(
|
||||
version: version.ToModel(),
|
||||
state: state,
|
||||
addresses: [.. nodeInfo.Addresses],
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
using System.Linq;
|
||||
|
||||
using FrostFS.Netmap;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public static class PlacementPolicyMapper
|
||||
{
|
||||
public static PlacementPolicy ToMessage(this ModelsV2.Netmap.PlacementPolicy placementPolicy)
|
||||
public static PlacementPolicy ToMessage(this FrostFsPlacementPolicy placementPolicy)
|
||||
{
|
||||
var pp = new PlacementPolicy
|
||||
{
|
||||
|
@ -23,9 +24,9 @@ public static class PlacementPolicyMapper
|
|||
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.Replicas.Select(replica => replica.ToModel()).ToArray()
|
||||
);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using FrostFS.Netmap;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public static class ReplicaMapper
|
||||
{
|
||||
public static Replica ToMessage(this ModelsV2.Netmap.Replica replica)
|
||||
public static Replica ToMessage(this FrostFsReplica 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;
|
||||
|
||||
internal static class ObjectMapper
|
||||
|
@ -8,7 +6,7 @@ internal static class ObjectMapper
|
|||
{
|
||||
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.SDK.ModelsV2;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -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 FrostFS.Object;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
using MatchType = FrostFS.Object.MatchType;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
|
@ -11,11 +10,11 @@ public static class ObjectFilterMapper
|
|||
{
|
||||
var objMatchTypeName = filter.MatchType switch
|
||||
{
|
||||
ModelsV2.Enums.ObjectMatchType.Unspecified => MatchType.Unspecified,
|
||||
ModelsV2.Enums.ObjectMatchType.Equals => MatchType.StringEqual,
|
||||
ModelsV2.Enums.ObjectMatchType.NotEquals => MatchType.StringNotEqual,
|
||||
ModelsV2.Enums.ObjectMatchType.KeyAbsent => MatchType.NotPresent,
|
||||
ModelsV2.Enums.ObjectMatchType.StartsWith => MatchType.CommonPrefix,
|
||||
FrostFsObjectMatchType.Unspecified => MatchType.Unspecified,
|
||||
FrostFsObjectMatchType.Equals => MatchType.StringEqual,
|
||||
FrostFsObjectMatchType.NotEquals => MatchType.StringNotEqual,
|
||||
FrostFsObjectMatchType.KeyAbsent => MatchType.NotPresent,
|
||||
FrostFsObjectMatchType.StartsWith => MatchType.CommonPrefix,
|
||||
|
||||
_ => throw new ArgumentException($"Unknown MatchType. Value: '{filter.MatchType}'.")
|
||||
};
|
||||
|
|
|
@ -1,75 +1,28 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using FrostFS.Object;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
using Google.Protobuf;
|
||||
using ObjectType = FrostFS.Object.ObjectType;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
public static class ObjectHeaderMapper
|
||||
{
|
||||
public static Header ToMessage(this ObjectHeader header)
|
||||
public static FrostFsObjectHeader ToModel(this Header header)
|
||||
{
|
||||
var objTypeName = header.ObjectType switch
|
||||
{
|
||||
ModelsV2.Enums.ObjectType.Regular => ObjectType.Regular,
|
||||
ModelsV2.Enums.ObjectType.Lock => ObjectType.Lock,
|
||||
ModelsV2.Enums.ObjectType.Tombstone => ObjectType.Tombstone,
|
||||
ObjectType.Regular => FrostFsObjectType.Regular,
|
||||
ObjectType.Lock => FrostFsObjectType.Lock,
|
||||
ObjectType.Tombstone => FrostFsObjectType.Tombstone,
|
||||
_ => throw new ArgumentException($"Unknown ObjectType. Value: '{header.ObjectType}'.")
|
||||
};
|
||||
|
||||
var head = new Header
|
||||
{
|
||||
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()
|
||||
};
|
||||
FrostFsSplit? 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(),
|
||||
ParentHeader = header.Split.ParentHeader?.ToModel(),
|
||||
|
@ -77,9 +30,20 @@ public static class ObjectHeaderMapper
|
|||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
public static class ObjectIdMapper
|
||||
{
|
||||
public static ObjectID ToMessage(this ObjectId objectId)
|
||||
public static ObjectID ToMessage(this FrostFsObjectId 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.SDK.Cryptography;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using System;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
|
@ -13,7 +15,7 @@ public static class OwnerIdMapper
|
|||
.SetSlidingExpiration(TimeSpan.FromHours(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))
|
||||
{
|
||||
|
@ -28,11 +30,11 @@ public static class OwnerIdMapper
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
using System;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
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
|
||||
{
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
using System;
|
||||
using FrostFS.SDK.ModelsV2.Enums;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
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)
|
||||
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
|
||||
? 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.Threading;
|
||||
using Version = FrostFS.Refs.Version;
|
||||
|
||||
using FrostFS.Refs;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
|
@ -10,7 +11,7 @@ public static class VersionMapper
|
|||
private static readonly Hashtable _cacheModels = [];
|
||||
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;
|
||||
|
||||
|
@ -31,7 +32,7 @@ public static class VersionMapper
|
|||
}
|
||||
catch (System.ArgumentException)
|
||||
{
|
||||
// ignore attempt to add duplicate error.
|
||||
// ignore attempt to add duplicate
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -43,7 +44,7 @@ public static class VersionMapper
|
|||
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;
|
||||
|
||||
|
@ -53,14 +54,14 @@ public static class VersionMapper
|
|||
try
|
||||
{
|
||||
_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);
|
||||
return model;
|
||||
}
|
||||
catch (System.ArgumentException)
|
||||
{
|
||||
// ignore attempt to add duplicate error.
|
||||
// ignore attempt to add duplicate
|
||||
}
|
||||
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,
|
||||
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,
|
||||
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.Collections.Generic;
|
||||
using FrostFS.SDK.ModelsV2.Enums;
|
||||
|
||||
namespace FrostFS.SDK.ModelsV2.Netmap;
|
||||
namespace FrostFS.SDK;
|
||||
|
||||
public class NodeInfo(
|
||||
Version version,
|
||||
public class FrostFsNodeInfo(
|
||||
FrostFsVersion version,
|
||||
NodeState state,
|
||||
IReadOnlyCollection<string> addresses,
|
||||
IReadOnlyDictionary<string, string> attributes,
|
||||
ReadOnlyMemory<byte> publicKey)
|
||||
{
|
||||
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 IReadOnlyDictionary<string, string> Attributes { get; private set; } = attributes;
|
||||
public ReadOnlyMemory<byte> PublicKey { get; private set; } = publicKey;
|
|
@ -1,14 +1,14 @@
|
|||
using System;
|
||||
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 int CompareTo(PlacementPolicy other)
|
||||
public int CompareTo(FrostFsPlacementPolicy other)
|
||||
{
|
||||
var notEqual = other == null
|
||||
|| 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 string Selector { get; set; }
|
||||
|
||||
public Replica(int count, string? selector = null)
|
||||
public FrostFsReplica(int count, string? selector = null)
|
||||
{
|
||||
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.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
using FrostFS.SDK.Cryptography;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
using Grpc.Core.Interceptors;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
@ -13,13 +15,13 @@ public class Context()
|
|||
{
|
||||
private List<Interceptor>? interceptors;
|
||||
|
||||
private ByteString publicKeyCache;
|
||||
private ByteString? publicKeyCache;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -35,11 +37,9 @@ public class Context()
|
|||
set { this.interceptors = value; }
|
||||
}
|
||||
|
||||
public ByteString PublicKeyCache
|
||||
public ByteString? GetPublicKeyCache()
|
||||
{
|
||||
get
|
||||
{
|
||||
if (publicKeyCache == null)
|
||||
if (publicKeyCache == null && Key != null)
|
||||
{
|
||||
publicKeyCache = ByteString.CopyFrom(Key.PublicKey());
|
||||
}
|
||||
|
@ -47,4 +47,3 @@ public class Context()
|
|||
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 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
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
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.
|
||||
/// </summary>
|
||||
/// <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;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public class PrmBase() : IContext
|
||||
{
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
using FrostFS.SDK.ModelsV2;
|
||||
using System.Security.Cryptography;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
|
||||
public sealed class PrmContainerCreate(ModelsV2.Container container) : PrmBase, ISessionToken
|
||||
public sealed class PrmContainerCreate(FrostFsContainerInfo container) : PrmBase, ISessionToken
|
||||
{
|
||||
public ModelsV2.Container Container { get; set; } = container;
|
||||
public FrostFsContainerInfo Container { get; set; } = container;
|
||||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
/// Blank session token
|
||||
/// </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(ContainerId containerId) : PrmBase, ISessionToken
|
||||
public sealed class PrmContainerDelete(FrostFsContainerId containerId) : PrmBase, ISessionToken
|
||||
{
|
||||
public ContainerId ContainerId { get; set; } = containerId;
|
||||
public FrostFsContainerId ContainerId { get; set; } = containerId;
|
||||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
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(ContainerId containerId) : PrmBase
|
||||
public sealed class PrmContainerGet(FrostFsContainerId container) : 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()
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public sealed class PrmNetmapSnapshot() : PrmBase
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public sealed class PrmNetworkSettings() : PrmBase
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
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(ContainerId containerId, ObjectId objectId) : PrmBase, ISessionToken
|
||||
public sealed class PrmObjectDelete(FrostFsContainerId containerId, FrostFsObjectId 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 />
|
||||
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(ContainerId containerId, ObjectId objectId) : PrmBase, ISessionToken
|
||||
public sealed class PrmObjectGet(FrostFsContainerId containerId, FrostFsObjectId 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 />
|
||||
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(ContainerId containerId, ObjectId objectId) : PrmBase, ISessionToken
|
||||
public sealed class PrmObjectHeadGet(FrostFsContainerId containerId, FrostFsObjectId 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 />
|
||||
public SessionToken? SessionToken { get; set; }
|
||||
public FrostFsSessionToken? SessionToken { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System.IO;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
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.
|
||||
/// </summary>
|
||||
/// <value>Header with required parameters to create an object</value>
|
||||
public ObjectHeader? Header { get; set; }
|
||||
public FrostFsObjectHeader? Header { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A stream with source data
|
||||
|
@ -37,7 +36,7 @@ public sealed class PrmObjectPut : PrmBase, ISessionToken
|
|||
public byte[]? CustomBuffer { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public SessionToken? SessionToken { get; set; }
|
||||
public FrostFsSessionToken? SessionToken { get; set; }
|
||||
|
||||
internal int MaxObjectSizeCache { get; set; }
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
using FrostFS.SDK.ModelsV2;
|
||||
using System.Collections.Generic;
|
||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
using System.Collections.Generic;
|
||||
|
||||
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>
|
||||
/// Defines container for the search
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public ContainerId ContainerId { get; set; } = containerId;
|
||||
public FrostFsContainerId ContainerId { get; set; } = containerId;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the search criteria
|
||||
|
@ -17,5 +17,5 @@ public sealed class PrmObjectSearch(ContainerId containerId, params IObjectFilte
|
|||
public IEnumerable<IObjectFilter> Filters { get; set; } = filters;
|
||||
|
||||
/// <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
|
||||
{
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public sealed class PrmSingleObjectPut(FrostFsObject frostFsObject) : PrmBase, ISessionToken
|
||||
{
|
||||
public FrostFsObject FrostFsObject { get; set; } = frostFsObject;
|
||||
|
||||
/// <inheritdoc />
|
||||
public SessionToken? SessionToken { get; set; }
|
||||
public FrostFsSessionToken? SessionToken { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
namespace FrostFS.SDK.ClientV2.Parameters;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public class PrmWait(TimeSpan timeout, TimeSpan pollInterval)
|
||||
{
|
||||
|
|
|
@ -3,12 +3,11 @@ using System.Collections.Generic;
|
|||
using System.Collections.Specialized;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC.Netmap;
|
||||
using FrostFS.SDK.ClientV2;
|
||||
using FrostFS.Container;
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
using FrostFS.SDK.ClientV2.Parameters;
|
||||
using FrostFS.SDK.ClientV2;
|
||||
using FrostFS.Refs;
|
||||
using FrostFS.Session;
|
||||
|
||||
|
@ -18,14 +17,14 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -34,13 +33,13 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
|||
return response.Body.Container.ToModel();
|
||||
}
|
||||
|
||||
internal async IAsyncEnumerable<ContainerId> ListContainersAsync(PrmContainerGetAll args)
|
||||
internal async IAsyncEnumerable<FrostFsContainerId> ListContainersAsync(PrmContainerGetAll args)
|
||||
{
|
||||
var ctx = args.Context!;
|
||||
|
||||
var request = new ListRequest
|
||||
{
|
||||
Body = new ListRequest.Types.Body
|
||||
Body = new ()
|
||||
{
|
||||
OwnerId = ctx.OwnerId.ToMessage()
|
||||
}
|
||||
|
@ -55,16 +54,18 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
|||
|
||||
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 grpcContainer = args.Container.ToMessage();
|
||||
grpcContainer.OwnerId = ctx.OwnerId.ToMessage();
|
||||
grpcContainer.Version = ctx.Version.ToMessage();
|
||||
|
||||
var grpcContainer = args.Container.GetContainer();
|
||||
|
||||
grpcContainer.OwnerId ??= ctx.OwnerId.ToMessage();
|
||||
grpcContainer.Version ??= ctx.Version.ToMessage();
|
||||
|
||||
var request = new PutRequest
|
||||
{
|
||||
|
@ -81,9 +82,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
|||
null,
|
||||
ContainerSessionContext.Types.Verb.Put,
|
||||
ctx.Key,
|
||||
ctx.PublicKeyCache);
|
||||
|
||||
var v = sessionToken.Body.OwnerId == grpcContainer.OwnerId;
|
||||
ctx.GetPublicKeyCache());
|
||||
|
||||
request.AddMetaHeader(args.XHeaders, sessionToken);
|
||||
|
||||
|
@ -95,7 +94,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
|||
|
||||
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)
|
||||
|
@ -116,7 +115,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
|||
request.Body.ContainerId,
|
||||
ContainerSessionContext.Types.Verb.Delete,
|
||||
ctx.Key,
|
||||
ctx.PublicKeyCache);
|
||||
ctx.GetPublicKeyCache());
|
||||
|
||||
request.AddMetaHeader(args.XHeaders, sessionToken);
|
||||
|
||||
|
@ -193,7 +192,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
|
|||
if (DateTime.UtcNow >= deadLine)
|
||||
throw new TimeoutException();
|
||||
|
||||
if (ex.Status.Code != ModelsV2.Enums.StatusCode.ContainerNotFound)
|
||||
if (ex.Status.Code != FrostFsStatusCode.ContainerNotFound)
|
||||
throw;
|
||||
|
||||
if (expect == WaitExpects.Removed)
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
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 FrostFS.SDK.ClientV2.Parameters;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
|
@ -40,7 +38,7 @@ internal class NetmapServiceProvider : ContextAccessor
|
|||
return settings;
|
||||
}
|
||||
|
||||
internal async Task<NodeInfo> GetLocalNodeInfoAsync(PrmNodeInfo args)
|
||||
internal async Task<FrostFsNodeInfo> GetLocalNodeInfoAsync(PrmNodeInfo args)
|
||||
{
|
||||
var ctx = args.Context!;
|
||||
var request = new LocalNodeInfoRequest
|
||||
|
@ -72,7 +70,7 @@ internal class NetmapServiceProvider : ContextAccessor
|
|||
return response;
|
||||
}
|
||||
|
||||
internal async Task<NetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot args)
|
||||
internal async Task<FrostFsNetmapSnapshot> GetNetmapSnapshotAsync(PrmNetmapSnapshot args)
|
||||
{
|
||||
var ctx = args.Context!;
|
||||
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
using FrostFS.Object;
|
||||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.ClientV2.Extensions;
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
using FrostFS.SDK.ClientV2;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.Session;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
using FrostFS.SDK.ClientV2.Extensions;
|
||||
using FrostFS.SDK.ClientV2.Parameters;
|
||||
using System.Buffers;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
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);
|
||||
|
||||
|
@ -26,16 +26,17 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
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 request = new HeadRequest
|
||||
{
|
||||
Body = new HeadRequest.Types.Body
|
||||
{
|
||||
Address = new Address
|
||||
{
|
||||
ContainerId = args.ContainerId.ToMessage(),
|
||||
ContainerId = args.ContainerId.ContainerID,
|
||||
ObjectId = args.ObjectId.ToMessage()
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
Verifier.CheckResponse(response);
|
||||
}
|
||||
|
||||
internal async IAsyncEnumerable<ObjectId> SearchObjectsAsync(PrmObjectSearch args)
|
||||
internal async IAsyncEnumerable<FrostFsObjectId> SearchObjectsAsync(PrmObjectSearch args)
|
||||
{
|
||||
var ctx = args.Context!;
|
||||
var request = new SearchRequest
|
||||
|
@ -149,11 +150,11 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
|
||||
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)
|
||||
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 grpcObject = ObjectTools.CreateObject(args.FrostFsObject, ctx);
|
||||
|
||||
var request = new PutSingleRequest
|
||||
{
|
||||
Body = new PutSingleRequest.Types.Body()
|
||||
{
|
||||
Object = grpcObject
|
||||
}
|
||||
Body = new () { Object = grpcObject }
|
||||
};
|
||||
|
||||
var sessionToken = await GetOrCreateSession(args, ctx);
|
||||
|
@ -202,15 +200,15 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
|
||||
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 tokenRaw = await GetOrCreateSession(args, ctx);
|
||||
var token = new ModelsV2.SessionToken(tokenRaw.Serialize());
|
||||
var token = new FrostFsSessionToken(tokenRaw.Serialize());
|
||||
|
||||
args.SessionToken = token;
|
||||
|
||||
|
@ -237,9 +235,9 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
var restPart = (restBytes % (ulong)objectSize) > 0 ? 1 : 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
|
||||
var attributes = args.Header!.Attributes;
|
||||
|
@ -249,7 +247,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
{
|
||||
if (split == null)
|
||||
{
|
||||
split = new Split();
|
||||
split = new FrostFsSplit();
|
||||
args.Header!.Attributes = [];
|
||||
}
|
||||
|
||||
|
@ -266,7 +264,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
// send the last part and create linkObject
|
||||
if (sentObjectIds.Count > 0)
|
||||
{
|
||||
var largeObjectHeader = new ObjectHeader(header.ContainerId) { PayloadLength = fullLength };
|
||||
var largeObjectHeader = new FrostFsObjectHeader(header.ContainerId) { PayloadLength = fullLength };
|
||||
|
||||
largeObjectHeader.Attributes.AddRange(attributes);
|
||||
|
||||
|
@ -276,7 +274,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
|
||||
sentObjectIds.Add(result.ObjectId);
|
||||
|
||||
var linkObject = new LinkObject(header.ContainerId, split!.SplitId, largeObjectHeader)
|
||||
var linkObject = new FrostFsLinkObject(header.ContainerId, split!.SplitId, largeObjectHeader)
|
||||
.AddChildren(sentObjectIds);
|
||||
|
||||
_ = await PutSingleObjectAsync(new PrmSingleObjectPut(linkObject) { Context = args.Context});
|
||||
|
@ -290,9 +288,9 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -359,7 +357,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
var response = await stream.Close();
|
||||
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
|
||||
{
|
||||
|
@ -374,10 +372,10 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
|
|||
{
|
||||
var header = args.Header!;
|
||||
|
||||
header.OwnerId = ctx.OwnerId;
|
||||
header.Version = ctx.Version;
|
||||
header.OwnerId ??= ctx.OwnerId;
|
||||
header.Version ??= ctx.Version;
|
||||
|
||||
var grpcHeader = header.ToMessage();
|
||||
var grpcHeader = header.GetHeader();
|
||||
|
||||
if (header.Split != null)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
using FrostFS.SDK.ClientV2.Parameters;
|
||||
using FrostFS.SDK.ClientV2;
|
||||
using FrostFS.Session;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
|
|
@ -4,5 +4,3 @@ internal class ContextAccessor(ClientEnvironment context)
|
|||
{
|
||||
protected ClientEnvironment Context { get; set; } = context;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
using System.Threading.Tasks;
|
||||
using FrostFS.SDK.ClientV2.Parameters;
|
||||
|
||||
using FrostFS.SDK.ClientV2;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
using FrostFS.SDK.ModelsV2;
|
||||
using Grpc.Net.Client;
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Buffers;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
using Grpc.Net.Client;
|
||||
|
||||
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;
|
||||
|
||||
internal OwnerId? Owner { get; } = owner;
|
||||
internal FrostFsOwner? Owner { get; } = owner;
|
||||
|
||||
internal GrpcChannel Channel { get; private set; } = channel;
|
||||
|
||||
internal ModelsV2.Version Version { get; } = version;
|
||||
internal FrostFsVersion Version { get; } = version;
|
||||
|
||||
internal NetworkSettings? NetworkSettings { get; set; }
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class ClientEnvironment(Client client, ECDsa? key, OwnerId? owner, GrpcCh
|
|||
{
|
||||
if (disposing)
|
||||
{
|
||||
Channel.Dispose();
|
||||
Channel?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Extensions;
|
||||
|
||||
|
@ -21,29 +19,29 @@ public static class ObjectExtensions
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
public static FrostFsObject AddAttribute(this FrostFsObject obj, ObjectAttribute attribute)
|
||||
public static FrostFsObject AddAttribute(this FrostFsObject obj, FrostFsAttribute attribute)
|
||||
{
|
||||
obj.Header.Attributes.Add(attribute);
|
||||
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);
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static FrostFsObject SetSplit(this FrostFsObject obj, Split? split)
|
||||
public static FrostFsObject SetSplit(this FrostFsObject obj, FrostFsSplit? split)
|
||||
{
|
||||
obj.Header.Split = split;
|
||||
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);
|
||||
return linkObject;
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.Threading.Tasks;
|
|||
using Grpc.Core;
|
||||
|
||||
using FrostFS.Object;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
using System.Threading;
|
||||
|
||||
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))
|
||||
return null;
|
||||
|
@ -44,14 +43,14 @@ public class ObjectReader(AsyncServerStreamingCall<GetResponse> call) : IObjectR
|
|||
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Chunk)
|
||||
throw new InvalidOperationException("unexpected message type");
|
||||
|
||||
return response.Body.Chunk.ToByteArray();
|
||||
return response.Body.Chunk.Memory;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
Call.Dispose();
|
||||
Call?.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
disposed = true;
|
||||
|
|
|
@ -30,6 +30,6 @@ internal class ObjectStreamer(AsyncClientStreamingCall<PutRequest, PutResponse>
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
Call.Dispose();
|
||||
Call?.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,12 @@ using FrostFS.Object;
|
|||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
internal class ObjectTools
|
||||
{
|
||||
internal static ObjectId CalculateObjectId(ObjectHeader header, Context ctx)
|
||||
internal static FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx)
|
||||
{
|
||||
var grpcHeader = CreateHeader(header, [], ctx);
|
||||
|
||||
|
@ -24,10 +23,10 @@ internal class ObjectTools
|
|||
|
||||
internal static Object.Object CreateObject(FrostFsObject @object, Context ctx)
|
||||
{
|
||||
@object.Header.OwnerId = ctx.OwnerId;
|
||||
@object.Header.Version = ctx.Version;
|
||||
@object.Header.OwnerId ??= ctx.OwnerId;
|
||||
@object.Header.Version ??= ctx.Version;
|
||||
|
||||
var grpcHeader = @object.Header.ToMessage();
|
||||
var grpcHeader = @object.Header.GetHeader();
|
||||
|
||||
grpcHeader.PayloadLength = (ulong)@object.Payload.Length;
|
||||
grpcHeader.PayloadHash = Sha256Checksum(@object.Payload);
|
||||
|
@ -47,18 +46,21 @@ internal class ObjectTools
|
|||
|
||||
obj.Signature = new Refs.Signature
|
||||
{
|
||||
Key = ctx.PublicKeyCache,
|
||||
Key = ctx.GetPublicKeyCache(),
|
||||
Sign = ByteString.CopyFrom(ctx.Key.SignData(obj.ObjectId.ToByteArray())),
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
SplitId = split.SplitId != null ? ByteString.CopyFrom(split.SplitId.ToBinary()) : null
|
||||
SplitId = split.SplitId?.GetSplitId()
|
||||
};
|
||||
|
||||
if (split.Children != null && split.Children.Count != 0)
|
||||
|
@ -72,7 +74,7 @@ internal class ObjectTools
|
|||
grpcHeader.Split.ParentHeader = grpcParentHeader;
|
||||
grpcHeader.Split.ParentSignature = new Refs.Signature
|
||||
{
|
||||
Key = ctx.PublicKeyCache,
|
||||
Key = ctx.GetPublicKeyCache(),
|
||||
Sign = ByteString.CopyFrom(ctx.Key.SignData(grpcHeader.Split.Parent.ToByteArray())),
|
||||
};
|
||||
|
||||
|
@ -82,12 +84,12 @@ internal class ObjectTools
|
|||
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();
|
||||
grpcHeader.Version = ctx.Version.ToMessage();
|
||||
var grpcHeader = header.GetHeader();
|
||||
|
||||
if (payload != null) // && payload.Length > 0
|
||||
grpcHeader.PayloadHash = Sha256Checksum(payload);
|
||||
|
|
|
@ -24,9 +24,7 @@ namespace System
|
|||
public Index(int value, bool fromEnd = false)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
||||
}
|
||||
|
||||
if (fromEnd)
|
||||
_value = ~value;
|
||||
|
@ -52,9 +50,7 @@ namespace System
|
|||
public static Index FromStart(int value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
||||
}
|
||||
|
||||
return new Index(value);
|
||||
}
|
||||
|
@ -65,9 +61,7 @@ namespace System
|
|||
public static Index FromEnd(int value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
|
||||
}
|
||||
|
||||
return new Index(~value);
|
||||
}
|
||||
|
@ -77,14 +71,7 @@ namespace System
|
|||
{
|
||||
get
|
||||
{
|
||||
if (_value < 0)
|
||||
{
|
||||
return ~_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
return _value < 0 ? ~_value : _value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,6 +189,7 @@ namespace System
|
|||
{
|
||||
int start;
|
||||
var startIndex = Start;
|
||||
|
||||
if (startIndex.IsFromEnd)
|
||||
start = length - startIndex.Value;
|
||||
else
|
||||
|
@ -209,15 +197,14 @@ namespace System
|
|||
|
||||
int end;
|
||||
var endIndex = End;
|
||||
|
||||
if (endIndex.IsFromEnd)
|
||||
end = length - endIndex.Value;
|
||||
else
|
||||
end = endIndex.Value;
|
||||
|
||||
if ((uint)end > (uint)length || (uint)start > (uint)end)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(length));
|
||||
}
|
||||
|
||||
return (start, end - start);
|
||||
}
|
||||
|
@ -234,9 +221,7 @@ namespace System.Runtime.CompilerServices
|
|||
public static T[] GetSubArray<T>(T[] array, Range range)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
(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[].
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var dest = new T[length];
|
||||
Array.Copy(array, offset, dest, 0, length);
|
||||
|
|
|
@ -5,7 +5,6 @@ using System.Security.Cryptography;
|
|||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.SDK.ModelsV2;
|
||||
using FrostFS.SDK.ProtosV2.Interfaces;
|
||||
using FrostFS.Session;
|
||||
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
using System;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.SDK.ProtosV2.Interfaces;
|
||||
using FrostFS.Session;
|
||||
|
||||
using Google.Protobuf;
|
||||
|
||||
using Org.BouncyCastle.Asn1.Sec;
|
||||
|
@ -9,11 +14,6 @@ using Org.BouncyCastle.Crypto.Parameters;
|
|||
using Org.BouncyCastle.Crypto.Signers;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.Session;
|
||||
using FrostFS.SDK.ProtosV2.Interfaces;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
public static class RequestSigner
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Grpc.Core;
|
||||
|
||||
using FrostFS.Object;
|
||||
using FrostFS.Refs;
|
||||
using System.Threading;
|
||||
|
||||
using Grpc.Core;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2;
|
||||
|
||||
|
@ -29,6 +29,6 @@ internal class SearchReader(AsyncServerStreamingCall<SearchResponse> call) : IDi
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
Call.Dispose();
|
||||
Call?.Dispose();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,12 @@
|
|||
using System;
|
||||
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 Org.BouncyCastle.Asn1.Sec;
|
||||
|
@ -9,12 +15,6 @@ using Org.BouncyCastle.Crypto.Parameters;
|
|||
using Org.BouncyCastle.Crypto.Signers;
|
||||
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;
|
||||
|
||||
public static class Verifier
|
||||
|
|
|
@ -2,7 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FrostFS.SDK.ModelsV2;
|
||||
namespace FrostFS.SDK;
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
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;
|
||||
|
||||
namespace FrostFS.SDK.ModelsV2.Enums;
|
||||
namespace FrostFS.SDK;
|
||||
|
||||
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