238 lines
No EOL
8 KiB
C#
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
|
|
} |