[#23] Client: Refactoring to optimize memory usage #28
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
|
||||
|
|
173
README.md
173
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)
|
||||
{
|
||||
var bytesCount = await stream.ReadAsync(buffer.AsMemory(0, partSize));
|
||||
|
||||
split.Previous = sentObjectIds.LastOrDefault();
|
||||
|
||||
largeObject.AppendBlock(buffer, bytesCount);
|
||||
|
||||
currentObject = new FrostFS.SDK.ModelsV2.Object(containerId, bytesCount < partSize ? buffer.Take(bytesCount).ToArray() : buffer)
|
||||
.AddAttribute(fileNameAttribute)
|
||||
.SetSplit(split);
|
||||
|
||||
if (largeObject.PayloadLength == fullLength)
|
||||
break;
|
||||
|
||||
var objectId = await fsClient.PutSingleObjectAsync(currentObject);
|
||||
sentObjectIds.Add(objectId);
|
||||
}
|
||||
|
||||
if (sentObjectIds.Any())
|
||||
{
|
||||
largeObject.CalculateHash()
|
||||
.AddAttribute(fileNameAttribute);
|
||||
|
||||
currentObject.SetParent(largeObject);
|
||||
|
||||
var objectId = await fsClient.PutSingleObjectAsync(currentObject);
|
||||
sentObjectIds.Add(objectId);
|
||||
|
||||
var linkObject = new LinkObject(containerId, split.SplitId, largeObject)
|
||||
.AddChildren(sentObjectIds)
|
||||
.AddAttribute(fileNameAttribute);
|
||||
|
||||
_ = await fsClient.PutSingleObjectAsync(linkObject);
|
||||
|
||||
return currentObject.GetParentId();
|
||||
}
|
||||
|
||||
return await fsClient.PutSingleObjectAsync(currentObject);
|
||||
await foreach (var cid in client.ListContainersAsync())
|
||||
{
|
||||
await client.DeleteContainerAsync(new PrmContainerDelete(cid));
|
||||
}
|
||||
|
||||
var placementPolicy = new FrostFsPlacementPolicy(true, new FrostFsReplica(1));
|
||||
|
||||
var createContainerParam = new PrmContainerCreate(
|
||||
new FrostFsContainerInfo(BasicAcl.PublicRW, new FrostFsPlacementPolicy(true, new FrostFsReplica(1))));
|
||||
|
||||
var containerId = await client.CreateContainerAsync(createContainerParam);
|
||||
|
||||
using var fileStream = File.OpenRead(@"C:\Users\Paul\Pictures\cat.jpeg");
|
||||
|
||||
var param = new PrmObjectPut
|
||||
{
|
||||
Header = new FrostFsObjectHeader(
|
||||
containerId: containerId,
|
||||
type: FrostFsObjectType.Regular,
|
||||
[new FrostFsAttribute("fileName", "test")]),
|
||||
Payload = fileStream
|
||||
};
|
||||
|
||||
FrostFsObjectId objectId = await client.PutObjectAsync(param);
|
||||
|
||||
var filter = new FilterByAttribute(FrostFsMatchType.Equals, "fileName", "test");
|
||||
|
||||
await foreach (var objId in client.SearchObjectsAsync(new PrmObjectSearch(containerId) { Filters = [filter] }))
|
||||
{
|
||||
var objHeader = await client.GetObjectHeadAsync(new PrmObjectHeadGet(containerId, objId));
|
||||
}
|
||||
|
||||
var @object = await client.GetObjectAsync(new PrmObjectGet(containerId, objectId));
|
||||
|
||||
var downloadedBytes = new byte[@object.Header.PayloadLength];
|
||||
MemoryStream ms = new(downloadedBytes);
|
||||
|
||||
ReadOnlyMemory<byte>? chunk = null;
|
||||
while ((chunk = await @object.ObjectReader!.ReadChunk()) != null)
|
||||
{
|
||||
ms.Write(chunk.Value.Span);
|
||||
}
|
||||
```
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
FrostFsMatchType.Unspecified => MatchType.Unspecified,
|
||||
FrostFsMatchType.Equals => MatchType.StringEqual,
|
||||
FrostFsMatchType.NotEquals => MatchType.StringNotEqual,
|
||||
FrostFsMatchType.KeyAbsent => MatchType.NotPresent,
|
||||
FrostFsMatchType.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 FrostFsMatchType
|
||||
{
|
||||
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 FrostFsMatchType MatchType { get; set; }
|
||||
public string Key { get; set; }
|
||||
|
||||
string? GetSerializedValue();
|
||||
}
|
||||
|
||||
public abstract class FrostFsObjectFilter<T>(FrostFsMatchType matchType, string key, T value) : IObjectFilter
|
||||
{
|
||||
public FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType 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(FrostFsMatchType matchType, FrostFsObjectId ecParentId) : FrostFsObjectFilter<FrostFsObjectId>(matchType, Constants.FilterHeaderECParent, ecParentId) { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates filter to search Root objects
|
||||
/// </summary>
|
||||
public class FilterByRootObject() : FrostFsObjectFilter<string>(FrostFsMatchType.Unspecified, Constants.FilterHeaderRoot, string.Empty) { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates filter to search objects that are physically stored on the server
|
||||
/// </summary
|
||||
public class FilterByPhysicallyStored() : FrostFsObjectFilter<string>(FrostFsMatchType.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,16 +37,13 @@ public class Context()
|
|||
set { this.interceptors = value; }
|
||||
}
|
||||
|
||||
public ByteString PublicKeyCache
|
||||
public ByteString? GetPublicKeyCache()
|
||||
{
|
||||
get
|
||||
if (publicKeyCache == null && Key != null)
|
||||
{
|
||||
if (publicKeyCache == null)
|
||||
{
|
||||
publicKeyCache = ByteString.CopyFrom(Key.PublicKey());
|
||||
}
|
||||
|
||||
return publicKeyCache;
|
||||
publicKeyCache = ByteString.CopyFrom(Key.PublicKey());
|
||||
}
|
||||
|
||||
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;
|
||||
dstepanov-yadro marked this conversation as resolved
|
||||
|
||||
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…
Add table
Reference in a new issue
As far as I remember, C# code style requires that namespace must correspond directory structure.
Yes, it one of the suggestion. Requirements are defined by vendor. As for me, folder hierarchy is useful for structuring, but dozens of using - are not, especially for external users. Do we have such a requirement?
No