[#21] Client: Allows multinenant client

Using one client for several owners

Signed-off-by: Pavel Gross <p.gross@yando.com>
This commit is contained in:
Pavel Gross 2024-08-12 10:46:59 +03:00
parent 18126ea763
commit 2a28806ace
30 changed files with 349 additions and 281 deletions

View file

@ -35,6 +35,11 @@ public class Client : IFrostFSClient
return new Client(clientOptions, channelOptions);
}
public static IFrostFSClient GetSingleOwnerInstance(IOptions<SingleOwnerClientSettings> clientOptions, GrpcChannelOptions? channelOptions = null)
{
return new Client(clientOptions, channelOptions);
}
/// <summary>
/// For test only. Provide custom implementation or mock object to inject required logic instead of internal gRPC client.
/// </summary>
@ -46,7 +51,7 @@ public class Client : IFrostFSClient
/// <param name="objectService">Object.ObjectService.ObjectServiceClient implementation</param>
/// <returns></returns>
public static IFrostFSClient GetTestInstance(
IOptions<ClientSettings> clientOptions,
IOptions<SingleOwnerClientSettings> clientOptions,
GrpcChannelOptions? channelOptions,
NetmapService.NetmapServiceClient netmapService,
SessionService.SessionServiceClient sessionService,
@ -57,18 +62,18 @@ public class Client : IFrostFSClient
}
private Client(
IOptions<ClientSettings> settings,
GrpcChannelOptions? channelOptions,
ContainerService.ContainerServiceClient containerService,
NetmapService.NetmapServiceClient netmapService,
SessionService.SessionServiceClient sessionService,
ObjectService.ObjectServiceClient objectService)
IOptions<SingleOwnerClientSettings> settings,
GrpcChannelOptions? channelOptions,
ContainerService.ContainerServiceClient containerService,
NetmapService.NetmapServiceClient netmapService,
SessionService.SessionServiceClient sessionService,
ObjectService.ObjectServiceClient objectService)
{
var ecdsaKey = settings.Value.Key.LoadWif();
OwnerId.FromKey(ecdsaKey);
ClientCtx = new ClientEnvironment(
this,
client: this,
key: ecdsaKey,
owner: OwnerId.FromKey(ecdsaKey),
channel: InitGrpcChannel(settings.Value.Host, channelOptions),
@ -86,6 +91,25 @@ public class Client : IFrostFSClient
clientSettings.Validate();
var channel = InitGrpcChannel(clientSettings.Host, channelOptions);
ClientCtx = new ClientEnvironment(
this,
key: null,
owner: null,
channel: channel,
version: new Version(2, 13));
// TODO: define timeout logic
// CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20) });
}
private Client(IOptions<SingleOwnerClientSettings> options, GrpcChannelOptions? channelOptions)
{
var clientSettings = (options?.Value) ?? throw new ArgumentException("Options must be initialized");
clientSettings.Validate();
var ecdsaKey = clientSettings.Key.LoadWif();
var channel = InitGrpcChannel(clientSettings.Host, channelOptions);
@ -221,22 +245,22 @@ public class Client : IFrostFSClient
#endregion
#region ToolsImplementation
public ObjectId CalculateObjectId(ObjectHeader header)
public ObjectId CalculateObjectId(ObjectHeader header, Context ctx)
{
if (header == null)
throw new ArgumentNullException(nameof(header));
return ObjectTools.CalculateObjectId(header, ClientCtx);
return ObjectTools.CalculateObjectId(header, ctx);
}
#endregion
private async void CheckFrostFsVersionSupport(Context? ctx = default)
{
var args = new PrmNodeInfo(ctx);
var args = new PrmNodeInfo { Context = ctx };
var service = GetNetmapService(args);
var localNodeInfo = await service.GetLocalNodeInfoAsync(args);
if (!localNodeInfo.Version.IsSupported(ClientCtx.Version))
if (!localNodeInfo.Version.IsSupported(args.Context!.Version))
{
var msg = $"FrostFS {localNodeInfo.Version} is not supported.";
throw new ApplicationException(msg);
@ -250,6 +274,31 @@ public class Client : IFrostFSClient
ctx.Context ??= new Context();
if (ctx.Context.Key == null)
{
if (ClientCtx.Key == null)
{
throw new Exception("Key is not initialized.");
}
ctx.Context.Key = ClientCtx.Key.ECDsaKey;
}
if (ctx.Context.OwnerId == null)
{
ctx.Context.OwnerId = ClientCtx.Owner ?? OwnerId.FromKey(ctx.Context.Key);
}
if (ctx.Context.Version == null)
{
if (ClientCtx.Version == null)
{
throw new Exception("Version is not initialized.");
}
ctx.Context.Version = ClientCtx.Version;
}
CallInvoker? callInvoker = null;
if (ctx.Context.Interceptors != null && ctx.Context.Interceptors.Count > 0)
{