Sandbox/Tools.cs
2025-02-19 11:20:29 +03:00

238 lines
No EOL
8 KiB
C#

using System.Collections.ObjectModel;
using System.Text;
using FrostFS.SDK;
using FrostFS.SDK.Client;
using FrostFS.SDK.Client.Interfaces;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.Extensions.Options;
class Tools
{
public static IFrostFSClient CreateClient(string key, string host)
{
var clientOptions = Options.Create(new ClientSettings { Key = key, Host = host });
Func<string, ChannelBase> grpcChannel = (url) => GrpcChannel.ForAddress(new Uri(url));
var client = FrostFSClient.GetInstance(clientOptions, grpcChannel);
return client;
}
#region Session
public static async Task<FrostFsSessionToken> GetSessionTokenAsync(IFrostFSClient client)
{
return await client.CreateSessionAsync(new PrmSessionCreate(int.MaxValue), default);
}
#endregion
#region Chain
public static async Task<ReadOnlyMemory<byte>> AddContainerChainRuleAsync(IFrostFSClient client, FrostFsContainerId containerId, string chainId, string[] actions)
{
var addChainPrm = new PrmApeChainAdd(
new FrostFsChainTarget(FrostFsTargetType.Container, containerId.GetValue()),
new FrostFsChain
{
ID = Encoding.ASCII.GetBytes(chainId),
Rules = [
new FrostFsRule
{
Status = RuleStatus.Allow,
Actions = new Actions(inverted: false, names: actions),
Resources = new Resource (inverted: false, names: [$"native:object/*"]),
Any = false,
Conditions = []
}
],
MatchType = RuleMatchType.DenyPriority
}
);
var result = await client.AddChainAsync(addChainPrm, default);
await Task.Delay(8000);
return result;
}
public static async Task RemoveContainerChainAsync(IFrostFSClient client, FrostFsContainerId containerId, string chainId)
{
var target = new FrostFsChainTarget(FrostFsTargetType.Container, containerId.GetValue());
var args = new PrmApeChainRemove(target, Encoding.ASCII.GetBytes(chainId));
await client.RemoveChainAsync(args, default);
}
// TODO: implement deserializer
public static async Task<byte[][]> ListContainerChainAsync(IFrostFSClient client, FrostFsContainerId containerId)
{
var target = new FrostFsChainTarget(FrostFsTargetType.Container, containerId.GetValue());
var args = new PrmApeChainList(target);
var list = await client.ListChainAsync(args, default);
return [.. list.Select(c => c.Raw.ToByteArray())];
}
#endregion
#region Container
public static async Task<FrostFsContainerId> CreateContainerAsync(IFrostFSClient client, FrostFsAttributePair[] attributes)
{
var createContainerParam = new PrmContainerCreate(
new FrostFsContainerInfo(
new FrostFsPlacementPolicy(true, 1, [], [], new FrostFsReplica(1)),
attributes),
PrmWait.DefaultParams);
return await client.CreateContainerAsync(createContainerParam, default);
}
public static async Task DeleteContainerAsync(IFrostFSClient client, FrostFsContainerId containerId)
{
var args = new PrmContainerDelete(containerId, new PrmWait(60, 5));
await client.DeleteContainerAsync(args, default);
}
public static async Task<ICollection<FrostFsContainerId>> ListContainersAsync(IFrostFSClient client, FrostFsContainerId containerId)
{
var args = new PrmContainerGetAll();
Collection<FrostFsContainerId> containers = [];
await foreach (var cid in client.ListContainersAsync(args, default))
{
containers.Add(cid);
}
return containers;
}
public static async Task Cleanup(IFrostFSClient client)
{
await foreach (var cid in client.ListContainersAsync(default, default))
{
await client.DeleteContainerAsync(new PrmContainerDelete(cid, PrmWait.DefaultParams), default);
}
}
#endregion
#region Object
public static async Task<FrostFsHeaderResult> GetObjectHeadAsync(IFrostFSClient client, FrostFsContainerId containerId, FrostFsObjectId objectId)
{
var args = new PrmObjectHeadGet(containerId, objectId);
return await client.GetObjectHeadAsync(args, default);
}
public static async Task<FrostFsObject> GetObjectAsync(IFrostFSClient client, FrostFsContainerId containerId, FrostFsObjectId objectId)
{
var args = new PrmObjectGet(containerId, objectId);
return await client.GetObjectAsync(args, default);
}
public static async Task<byte[]> GetRangeAsync(IFrostFSClient client, FrostFsContainerId containerId, FrostFsObjectId objectId)
{
var args = new PrmRangeGet(containerId, objectId, new FrostFsRange(64, 128));
var rangeReader = await client.GetRangeAsync(args, default);
var downloadedBytes = new byte[128];
MemoryStream ms = new(downloadedBytes);
ReadOnlyMemory<byte>? chunk;
while ((chunk = await rangeReader!.ReadChunk()) != null)
{
ms.Write(chunk.Value.Span);
}
return downloadedBytes;
}
public static async Task<ReadOnlyMemory<byte>[]> GetRangeHashAsync(IFrostFSClient client, FrostFsContainerId containerId, FrostFsObjectId objectId)
{
Random rnd = new();
var salt = new byte[32];
rnd.NextBytes(salt);
var args = new PrmRangeHashGet(containerId, objectId, [new FrostFsRange(100, 64)], salt);
return await client.GetRangeHashAsync(args, default);
}
public static async Task<FrostFsObjectId> PutObjectAsync(IFrostFSClient client, FrostFsContainerId containerId, byte[] bytes)
{
var args = new PrmObjectPut(
new FrostFsObjectHeader(
containerId: containerId,
type: FrostFsObjectType.Regular,
[new FrostFsAttributePair("fileName", "test")]));
var stream = await client.PutObjectAsync(args, default);
await stream.WriteAsync(bytes.AsMemory());
var objectId = await stream.CompleteAsync();
return objectId;
}
public static async Task<FrostFsObjectId> PutSingleObjectAsync(IFrostFSClient client, FrostFsContainerId container, byte[] bytes)
{
var header = new FrostFsObjectHeader(
containerId: container,
type: FrostFsObjectType.Regular,
attributes: null,
split: null,
owner: null,
version: null);
var obj = new FrostFsObject(header);
var args = new PrmSingleObjectPut(obj);
return await client.PutSingleObjectAsync(args, default);
}
public static async Task<FrostFsObjectId> PatchObjectAsync(IFrostFSClient client, FrostFsContainerId containerId, FrostFsObjectId objectId, byte[] patch)
{
var range = new FrostFsRange(64, (ulong)patch.Length);
var args = new PrmObjectPatch(
new FrostFsAddress(containerId, objectId),
payload: new MemoryStream(patch),
maxChunkLength: 256,
range: range);
return await client.PatchObjectAsync(args, default);
}
public static async Task DeleteObjectAsync(IFrostFSClient client, FrostFsContainerId containerId, FrostFsObjectId objectId, byte[] patch)
{
var args = new PrmObjectDelete(containerId, objectId);
await client.DeleteObjectAsync(args, default);
}
public static async Task<ICollection<FrostFsObjectId>> SearchObjectsAsync(IFrostFSClient client, FrostFsContainerId containerId)
{
var filter = new FilterByAttributePair(FrostFsMatchType.Equals, "fileName", "test");
var args = new PrmObjectSearch(containerId, null, [], filter);
Collection<FrostFsObjectId> objects = [];
await foreach (var objId in client.SearchObjectsAsync(args, default))
{
objects.Add(objId);
}
return objects;
}
#endregion
}