using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using FrostFS.Container; using FrostFS.Netmap; using FrostFS.Object; using FrostFS.SDK.ClientV2.Interfaces; using FrostFS.SDK.Cryptography; using FrostFS.SDK.ModelsV2; using FrostFS.Session; using Grpc.Core; using Grpc.Net.Client; using static FrostFS.Netmap.NetworkConfig.Types; using Version = FrostFS.SDK.ModelsV2.Version; namespace FrostFS.SDK.ClientV2; public partial class Client: IFrostFSClient { private GrpcChannel? _channel; private readonly ECDsa _key; public readonly OwnerId OwnerId; public readonly Version Version = new(2, 13); private readonly Dictionary NetworkSettings = []; private ContainerService.ContainerServiceClient? _containerServiceClient; private NetmapService.NetmapServiceClient? _netmapServiceClient; private ObjectService.ObjectServiceClient? _objectServiceClient; private SessionService.SessionServiceClient? _sessionServiceClient; public static IFrostFSClient GetInstance(string key, string host) { return new Client(key, host); } private Client(string key, string host) { // TODO: Развязать клиент и реализацию GRPC _key = key.LoadWif(); OwnerId = OwnerId.FromKey(_key); InitGrpcChannel(host); InitContainerClient(); InitNetmapClient(); InitObjectClient(); InitSessionClient(); CheckFrostFsVersionSupport(); InitNetworkInfoAsync(); } private async void InitNetworkInfoAsync() { var info = await GetNetworkInfoAsync(); foreach (var param in info.Body.NetworkInfo.NetworkConfig.Parameters) { SetNetworksParam(param); } } private void SetNetworksParam(Parameter param) { var key = Encoding.UTF8.GetString(param.Key.ToByteArray()); var encodedValue = param.Value.ToByteArray(); ulong val = 0; for (var i = encodedValue.Length - 1; i >= 0; i--) { val = (val << 8) + encodedValue[i]; } NetworkSettings.Add(key, val); } private async void CheckFrostFsVersionSupport() { var localNodeInfo = await GetLocalNodeInfoAsync(); if (!localNodeInfo.Version.IsSupported(Version)) { var msg = $"FrostFS {localNodeInfo.Version} is not supported."; Console.WriteLine(msg); throw new ApplicationException(msg); } } private void InitGrpcChannel(string host) { Uri uri; try { uri = new Uri(host); } catch (UriFormatException e) { var msg = $"Host '{host}' has invalid format. Error: {e.Message}"; Console.WriteLine(msg); throw new ArgumentException(msg); } ChannelCredentials grpcCredentials; switch (uri.Scheme) { case "https": grpcCredentials = ChannelCredentials.SecureSsl; break; case "http": grpcCredentials = ChannelCredentials.Insecure; break; default: var msg = $"Host '{host}' has invalid URI scheme: '{uri.Scheme}'."; Console.WriteLine(msg); throw new ArgumentException(msg); } _channel = GrpcChannel.ForAddress(uri, new GrpcChannelOptions { Credentials = grpcCredentials, HttpHandler = new System.Net.Http.HttpClientHandler() }); } private void InitContainerClient() { _containerServiceClient = new ContainerService.ContainerServiceClient(_channel); } private void InitNetmapClient() { _netmapServiceClient = new NetmapService.NetmapServiceClient(_channel); } private void InitObjectClient() { _objectServiceClient = new ObjectService.ObjectServiceClient(_channel); } private void InitSessionClient() { _sessionServiceClient = new SessionService.SessionServiceClient(_channel); } }