[#26] All: Remove V2 from naming
Rename project, namespaces and class names Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
parent
c406df1a78
commit
766f61a5f7
219 changed files with 219 additions and 974 deletions
233
src/FrostFS.SDK.Client/Services/ContainerServiceProvider.cs
Normal file
233
src/FrostFS.SDK.Client/Services/ContainerServiceProvider.cs
Normal file
|
@ -0,0 +1,233 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using FrostFS.Container;
|
||||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.Client;
|
||||
using FrostFS.SDK.Client.Mappers.GRPC;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.Session;
|
||||
|
||||
namespace FrostFS.SDK.Client;
|
||||
|
||||
internal sealed class ContainerServiceProvider(ContainerService.ContainerServiceClient service, ClientContext clientCtx) : ContextAccessor(clientCtx), ISessionProvider
|
||||
{
|
||||
private SessionProvider? sessions;
|
||||
|
||||
public async ValueTask<SessionToken> GetOrCreateSession(ISessionToken args, CallContext ctx)
|
||||
{
|
||||
sessions ??= new(ClientContext);
|
||||
|
||||
if (ClientContext.SessionCache.Cache != null &&
|
||||
ClientContext.SessionCache.Cache.ContainsKey(ClientContext.SessionCacheKey))
|
||||
{
|
||||
return (SessionToken)ClientContext.SessionCache.Cache[ClientContext.SessionCacheKey];
|
||||
}
|
||||
|
||||
return await sessions.GetOrCreateSession(args, ctx).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal async Task<FrostFsContainerInfo> GetContainerAsync(PrmContainerGet args)
|
||||
{
|
||||
GetRequest request = GetContainerRequest(args.Container.ContainerID, args.XHeaders, args.Context);
|
||||
|
||||
var response = await service.GetAsync(request, null, args.Context.Deadline, args.Context.CancellationToken);
|
||||
|
||||
Verifier.CheckResponse(response);
|
||||
|
||||
return response.Body.Container.ToModel();
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
};
|
||||
|
||||
request.AddMetaHeader(args.XHeaders);
|
||||
request.Sign(ctx.Key);
|
||||
|
||||
var response = await service.ListAsync(request, null, ctx.Deadline, ctx.CancellationToken);
|
||||
|
||||
Verifier.CheckResponse(response);
|
||||
|
||||
foreach (var cid in response.Body.ContainerIds)
|
||||
{
|
||||
yield return new FrostFsContainerId(Base58.Encode(cid.Value.ToByteArray()));
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task<FrostFsContainerId> CreateContainerAsync(PrmContainerCreate args)
|
||||
{
|
||||
var ctx = args.Context!;
|
||||
|
||||
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));
|
||||
|
||||
var request = new PutRequest
|
||||
{
|
||||
Body = new PutRequest.Types.Body
|
||||
{
|
||||
Container = grpcContainer,
|
||||
Signature = ctx.Key.SignRFC6979(grpcContainer)
|
||||
}
|
||||
};
|
||||
|
||||
var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
|
||||
|
||||
sessionToken.CreateContainerTokenContext(
|
||||
null,
|
||||
ContainerSessionContext.Types.Verb.Put,
|
||||
ctx.Key,
|
||||
ctx.GetPublicKeyCache()!);
|
||||
|
||||
request.AddMetaHeader(args.XHeaders, sessionToken);
|
||||
|
||||
request.Sign(ctx.Key);
|
||||
|
||||
var response = await service.PutAsync(request, null, ctx.Deadline, ctx.CancellationToken);
|
||||
|
||||
Verifier.CheckResponse(response);
|
||||
|
||||
await WaitForContainer(WaitExpects.Exists, response.Body.ContainerId, args.WaitParams, ctx).ConfigureAwait(false);
|
||||
|
||||
return new FrostFsContainerId(response.Body.ContainerId);
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
};
|
||||
|
||||
var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
|
||||
|
||||
sessionToken.CreateContainerTokenContext(
|
||||
request.Body.ContainerId,
|
||||
ContainerSessionContext.Types.Verb.Delete,
|
||||
ctx.Key,
|
||||
ctx.GetPublicKeyCache()!);
|
||||
|
||||
request.AddMetaHeader(args.XHeaders, sessionToken);
|
||||
|
||||
request.Sign(ctx.Key);
|
||||
|
||||
var response = await service.DeleteAsync(request, null, ctx.Deadline, ctx.CancellationToken);
|
||||
|
||||
Verifier.CheckResponse(response);
|
||||
|
||||
await WaitForContainer(WaitExpects.Removed, request.Body.ContainerId, args.WaitParams, ctx)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Verifier.CheckResponse(response);
|
||||
}
|
||||
|
||||
private static GetRequest GetContainerRequest(ContainerID id, NameValueCollection? xHeaders, CallContext ctx)
|
||||
{
|
||||
if (ctx.Key == null)
|
||||
throw new ArgumentNullException(nameof(ctx), "Key is null");
|
||||
|
||||
var request = new GetRequest
|
||||
{
|
||||
Body = new GetRequest.Types.Body
|
||||
{
|
||||
ContainerId = id
|
||||
}
|
||||
};
|
||||
|
||||
request.AddMetaHeader(xHeaders);
|
||||
request.Sign(ctx.Key);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private enum WaitExpects
|
||||
{
|
||||
Exists,
|
||||
Removed
|
||||
}
|
||||
|
||||
private async Task WaitForContainer(WaitExpects expect, ContainerID id, PrmWait? waitParams, CallContext ctx)
|
||||
{
|
||||
var request = GetContainerRequest(id, null, ctx);
|
||||
|
||||
async Task action()
|
||||
{
|
||||
var response = await service.GetAsync(request, null, ctx.Deadline, ctx.CancellationToken);
|
||||
Verifier.CheckResponse(response);
|
||||
}
|
||||
|
||||
await WaitFor(action, expect, waitParams).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task WaitFor(
|
||||
Func<Task> action,
|
||||
WaitExpects expect,
|
||||
PrmWait? waitParams)
|
||||
{
|
||||
waitParams ??= PrmWait.DefaultParams;
|
||||
var deadLine = waitParams.GetDeadline();
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
await action().ConfigureAwait(false);
|
||||
|
||||
if (expect == WaitExpects.Exists)
|
||||
return;
|
||||
|
||||
if (DateTime.UtcNow >= deadLine)
|
||||
throw new TimeoutException();
|
||||
|
||||
await Task.Delay(waitParams.PollInterval).ConfigureAwait(false);
|
||||
}
|
||||
catch (FrostFsResponseException ex)
|
||||
{
|
||||
if (DateTime.UtcNow >= deadLine)
|
||||
throw new TimeoutException();
|
||||
|
||||
if (ex.Status?.Code != FrostFsStatusCode.ContainerNotFound)
|
||||
throw;
|
||||
|
||||
if (expect == WaitExpects.Removed)
|
||||
return;
|
||||
|
||||
await Task.Delay(waitParams.PollInterval).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue