[#28] Client: Apply code optimizations

Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
Pavel Gross 2024-11-18 16:57:20 +03:00
parent 766f61a5f7
commit 749000a090
57 changed files with 845 additions and 1116 deletions

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Cryptography;
using System.Threading.Tasks;
using FrostFS.Container;
@ -12,26 +13,34 @@ using FrostFS.Session;
namespace FrostFS.SDK.Client;
internal sealed class ContainerServiceProvider(ContainerService.ContainerServiceClient service, ClientContext clientCtx) : ContextAccessor(clientCtx), ISessionProvider
internal sealed class ContainerServiceProvider(ContainerService.ContainerServiceClient service, ClientContext clientCtx) : ContextAccessor(clientCtx)
{
private SessionProvider? sessions;
public async ValueTask<SessionToken> GetOrCreateSession(ISessionToken args, CallContext ctx)
public async ValueTask<FrostFsSessionToken> GetDefaultSession(ISessionToken args, CallContext ctx)
{
sessions ??= new(ClientContext);
if (ClientContext.SessionCache.Cache != null &&
ClientContext.SessionCache.Cache.ContainsKey(ClientContext.SessionCacheKey))
if (!ClientContext.SessionCache!.TryGetValue(ClientContext.SessionCacheKey, out var token))
{
return (SessionToken)ClientContext.SessionCache.Cache[ClientContext.SessionCacheKey];
var protoToken = await sessions.GetDefaultSession(args, ctx).ConfigureAwait(false);
token = new FrostFsSessionToken(protoToken);
ClientContext.SessionCache.SetValue(ClientContext.SessionCacheKey, token);
}
return await sessions.GetOrCreateSession(args, ctx).ConfigureAwait(false);
if (token == null)
{
throw new FrostFsException("Cannot create session");
}
return token;
}
internal async Task<FrostFsContainerInfo> GetContainerAsync(PrmContainerGet args)
{
GetRequest request = GetContainerRequest(args.Container.ContainerID, args.XHeaders, args.Context);
GetRequest request = GetContainerRequest(args.Container.ContainerID, args.XHeaders, ClientContext.Key.ECDsaKey);
var response = await service.GetAsync(request, null, args.Context.Deadline, args.Context.CancellationToken);
@ -43,24 +52,17 @@ internal sealed class ContainerServiceProvider(ContainerService.ContainerService
internal async IAsyncEnumerable<FrostFsContainerId> ListContainersAsync(PrmContainerGetAll args)
{
var ctx = args.Context!;
ctx.OwnerId ??= ClientContext.Owner;
ctx.Key ??= ClientContext.Key?.ECDsaKey;
if (ctx.Key == null)
throw new ArgumentNullException(nameof(args), "Key is null");
if (ctx.OwnerId == null)
throw new ArgumentException(nameof(ctx.OwnerId));
var request = new ListRequest
{
Body = new()
{
OwnerId = ctx.OwnerId.ToMessage()
OwnerId = ClientContext.Owner.OwnerID
}
};
request.AddMetaHeader(args.XHeaders);
request.Sign(ctx.Key);
request.Sign(ClientContext.Key.ECDsaKey);
var response = await service.ListAsync(request, null, ctx.Deadline, ctx.CancellationToken);
@ -68,7 +70,7 @@ internal sealed class ContainerServiceProvider(ContainerService.ContainerService
foreach (var cid in response.Body.ContainerIds)
{
yield return new FrostFsContainerId(Base58.Encode(cid.Value.ToByteArray()));
yield return new FrostFsContainerId(Base58.Encode(cid.Value.Span));
}
}
@ -78,36 +80,28 @@ internal sealed class ContainerServiceProvider(ContainerService.ContainerService
var grpcContainer = args.Container.GetContainer();
grpcContainer.OwnerId ??= ctx.OwnerId?.ToMessage();
grpcContainer.Version ??= ctx.Version?.ToMessage();
if (ctx.Key == null)
throw new ArgumentNullException(nameof(args), "Key is null");
if (grpcContainer.OwnerId == null)
throw new ArgumentException(nameof(grpcContainer.OwnerId));
if (grpcContainer.Version == null)
throw new ArgumentException(nameof(grpcContainer.Version));
grpcContainer.OwnerId ??= ClientContext.Owner.OwnerID;
grpcContainer.Version ??= ClientContext.Version.VersionID;
var request = new PutRequest
{
Body = new PutRequest.Types.Body
{
Container = grpcContainer,
Signature = ctx.Key.SignRFC6979(grpcContainer)
Signature = ClientContext.Key.ECDsaKey.SignRFC6979(grpcContainer)
}
};
var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
var sessionToken = (args.SessionToken ?? await GetDefaultSession(args, ctx).ConfigureAwait(false)) ?? throw new FrostFsException("Cannot create session token");
sessionToken.CreateContainerTokenContext(
var protoToken = sessionToken.CreateContainerToken(
null,
ContainerSessionContext.Types.Verb.Put,
ctx.Key,
ctx.GetPublicKeyCache()!);
ClientContext.Key);
request.AddMetaHeader(args.XHeaders, sessionToken);
request.AddMetaHeader(args.XHeaders, protoToken);
request.Sign(ctx.Key);
request.Sign(ClientContext.Key.ECDsaKey);
var response = await service.PutAsync(request, null, ctx.Deadline, ctx.CancellationToken);
@ -121,29 +115,26 @@ internal sealed class ContainerServiceProvider(ContainerService.ContainerService
internal async Task DeleteContainerAsync(PrmContainerDelete args)
{
var ctx = args.Context!;
if (ctx.Key == null)
throw new ArgumentNullException(nameof(args), "Key is null");
var request = new DeleteRequest
{
Body = new DeleteRequest.Types.Body
{
ContainerId = args.ContainerId.ToMessage(),
Signature = ctx.Key.SignRFC6979(args.ContainerId.ToMessage().Value)
Signature = ClientContext.Key.ECDsaKey.SignRFC6979(args.ContainerId.ToMessage().Value)
}
};
var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
var sessionToken = args.SessionToken ?? await GetDefaultSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateContainerTokenContext(
var protoToken = sessionToken.CreateContainerToken(
request.Body.ContainerId,
ContainerSessionContext.Types.Verb.Delete,
ctx.Key,
ctx.GetPublicKeyCache()!);
ClientContext.Key);
request.AddMetaHeader(args.XHeaders, sessionToken);
request.AddMetaHeader(args.XHeaders, protoToken);
request.Sign(ctx.Key);
request.Sign(ClientContext.Key.ECDsaKey);
var response = await service.DeleteAsync(request, null, ctx.Deadline, ctx.CancellationToken);
@ -155,11 +146,8 @@ internal sealed class ContainerServiceProvider(ContainerService.ContainerService
Verifier.CheckResponse(response);
}
private static GetRequest GetContainerRequest(ContainerID id, NameValueCollection? xHeaders, CallContext ctx)
private static GetRequest GetContainerRequest(ContainerID id, NameValueCollection? xHeaders, ECDsa key)
{
if (ctx.Key == null)
throw new ArgumentNullException(nameof(ctx), "Key is null");
var request = new GetRequest
{
Body = new GetRequest.Types.Body
@ -169,7 +157,7 @@ internal sealed class ContainerServiceProvider(ContainerService.ContainerService
};
request.AddMetaHeader(xHeaders);
request.Sign(ctx.Key);
request.Sign(key);
return request;
}
@ -182,7 +170,7 @@ internal sealed class ContainerServiceProvider(ContainerService.ContainerService
private async Task WaitForContainer(WaitExpects expect, ContainerID id, PrmWait? waitParams, CallContext ctx)
{
var request = GetContainerRequest(id, null, ctx);
var request = GetContainerRequest(id, null, ClientContext.Key.ECDsaKey);
async Task action()
{