[#1] Add response checker
Signed-off-by: Ivan Pchelintsev <i.pchelintsev@yadro.com>
This commit is contained in:
parent
8cacbcc8e9
commit
ae3fc419a4
6 changed files with 91 additions and 10 deletions
19
src/FrostFS.SDK.ClientV2/Mappers/GRPC/Status.cs
Normal file
19
src/FrostFS.SDK.ClientV2/Mappers/GRPC/Status.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using FrostFS.SDK.ModelsV2.Enums;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
|
||||
public static class StatusMapper
|
||||
{
|
||||
public static ModelsV2.Status ToModel(this Status.Status status)
|
||||
{
|
||||
if (status is null) return new ModelsV2.Status(StatusCode.Success);
|
||||
var codeName = Enum.GetName(typeof(StatusCode), status.Code);
|
||||
if (codeName is null)
|
||||
{
|
||||
throw new ArgumentException($"Unknown StatusCode. Value: '{status.Code}'.");
|
||||
}
|
||||
|
||||
return new ModelsV2.Status(Enum.Parse<StatusCode>(codeName), status.Message);
|
||||
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ public partial class Client
|
|||
request.AddMetaHeader();
|
||||
request.Sign(_key);
|
||||
var response = await _containerServiceClient.GetAsync(request);
|
||||
Verifier.CheckResponse(response);
|
||||
return response.Body.Container.ToModel();
|
||||
}
|
||||
|
||||
|
@ -33,6 +34,7 @@ public partial class Client
|
|||
request.AddMetaHeader();
|
||||
request.Sign(_key);
|
||||
var response = await _containerServiceClient.ListAsync(request);
|
||||
Verifier.CheckResponse(response);
|
||||
foreach (var cid in response.Body.ContainerIds)
|
||||
{
|
||||
yield return ContainerId.FromHash(cid.Value.ToByteArray());
|
||||
|
@ -55,7 +57,7 @@ public partial class Client
|
|||
request.AddMetaHeader();
|
||||
request.Sign(_key);
|
||||
var response = await _containerServiceClient.PutAsync(request);
|
||||
RequestVerifier.ProcessResponse(response);
|
||||
Verifier.CheckResponse(response);
|
||||
return ContainerId.FromHash(response.Body.ContainerId.Value.ToByteArray());
|
||||
}
|
||||
|
||||
|
@ -71,6 +73,7 @@ public partial class Client
|
|||
};
|
||||
request.AddMetaHeader();
|
||||
request.Sign(_key);
|
||||
await _containerServiceClient.DeleteAsync(request);
|
||||
var response = await _containerServiceClient.DeleteAsync(request);
|
||||
Verifier.CheckResponse(response);
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ public partial class Client
|
|||
request.AddMetaHeader();
|
||||
request.Sign(_key);
|
||||
var response = await _objectServiceClient.HeadAsync(request);
|
||||
Verifier.CheckResponse(response);
|
||||
return response.Body.Header.Header.ToModel();
|
||||
}
|
||||
|
||||
|
@ -55,8 +56,8 @@ public partial class Client
|
|||
);
|
||||
request.Sign(_key);
|
||||
|
||||
var response = await GetObject(request);
|
||||
return response.ToModel();
|
||||
var obj = await GetObject(request);
|
||||
return obj.ToModel();
|
||||
}
|
||||
|
||||
private async Task<Object.Object> GetObject(GetRequest request)
|
||||
|
@ -146,6 +147,7 @@ public partial class Client
|
|||
}
|
||||
|
||||
var response = await stream.Close();
|
||||
Verifier.CheckResponse(response);
|
||||
return ObjectId.FromHash(response.Body.ObjectId.Value.ToByteArray());
|
||||
}
|
||||
|
||||
|
@ -176,7 +178,8 @@ public partial class Client
|
|||
};
|
||||
request.AddMetaHeader();
|
||||
request.Sign(_key);
|
||||
await _objectServiceClient.DeleteAsync(request);
|
||||
var response = await _objectServiceClient.DeleteAsync(request);
|
||||
Verifier.CheckResponse(response);
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<ObjectId> SearchObjectsAsync(ContainerId cid, params ObjectFilter[] filters)
|
||||
|
@ -245,6 +248,7 @@ internal class ObjectReader : IDisposable
|
|||
}
|
||||
|
||||
var response = Call.ResponseStream.Current;
|
||||
Verifier.CheckResponse(response);
|
||||
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Init)
|
||||
throw new InvalidOperationException("unexpect message type");
|
||||
return new Object.Object
|
||||
|
@ -262,6 +266,7 @@ internal class ObjectReader : IDisposable
|
|||
}
|
||||
|
||||
var response = Call.ResponseStream.Current;
|
||||
Verifier.CheckResponse(response);
|
||||
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Chunk)
|
||||
throw new InvalidOperationException("unexpect message type");
|
||||
return response.Body.Chunk.ToByteArray();
|
||||
|
@ -311,6 +316,7 @@ internal class SearchReader : IDisposable
|
|||
}
|
||||
|
||||
var response = Call.ResponseStream.Current;
|
||||
Verifier.CheckResponse(response);
|
||||
return response.Body?.IdList.ToList();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Security.Cryptography;
|
||||
using FrostFS.Refs;
|
||||
using FrostFS.SDK.ClientV2.Mappers.GRPC;
|
||||
using FrostFS.SDK.Cryptography;
|
||||
using FrostFS.Session;
|
||||
using Google.Protobuf;
|
||||
|
@ -9,8 +10,9 @@ using Org.BouncyCastle.Crypto.Parameters;
|
|||
using Org.BouncyCastle.Crypto.Signers;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace FrostFS.SDK.ClientV2 {
|
||||
public static class RequestVerifier
|
||||
namespace FrostFS.SDK.ClientV2
|
||||
{
|
||||
public static class Verifier
|
||||
{
|
||||
public const int RFC6979SignatureSize = 64;
|
||||
|
||||
|
@ -73,11 +75,15 @@ namespace FrostFS.SDK.ClientV2 {
|
|||
return VerifyMatryoskaLevel(message.GetBody(), message.GetMetaHeader(), message.GetVerificationHeader());
|
||||
}
|
||||
|
||||
public static void ProcessResponse(IResponse resp)
|
||||
public static void CheckResponse(IResponse resp)
|
||||
{
|
||||
Console.WriteLine(resp.MetaHeader.Status);
|
||||
if (!resp.Verify())
|
||||
throw new FormatException($"invalid response, type={resp.GetType()}");
|
||||
var status = resp.MetaHeader.Status.ToModel();
|
||||
if (!status.IsSuccess())
|
||||
{
|
||||
throw new ApplicationException(status.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
src/FrostFS.SDK.ModelsV2/Enums/StatusCode.cs
Normal file
22
src/FrostFS.SDK.ModelsV2/Enums/StatusCode.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace FrostFS.SDK.ModelsV2.Enums;
|
||||
|
||||
public enum StatusCode
|
||||
{
|
||||
Success = 0,
|
||||
Internal = 1024,
|
||||
WrongMagicNumber = 1025,
|
||||
SignatureVerificationFailure = 1026,
|
||||
NodeUnderMaintenance = 1027,
|
||||
ObjectAccessDenied = 2048,
|
||||
ObjectNotFound = 2049,
|
||||
ObjectLocked = 2050,
|
||||
LockNotRegularObject = 2051,
|
||||
ObjectAlreadyRemoved = 2052,
|
||||
OutOfRange = 2053,
|
||||
ContainerNotFound = 3072,
|
||||
EAclNotFound = 3073,
|
||||
ContainerAccessDenied = 3074,
|
||||
TokenNotFound = 4096,
|
||||
TokenExpired = 4097,
|
||||
ApeManagerAccessDenied = 5120
|
||||
}
|
25
src/FrostFS.SDK.ModelsV2/Status.cs
Normal file
25
src/FrostFS.SDK.ModelsV2/Status.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using FrostFS.SDK.ModelsV2.Enums;
|
||||
|
||||
namespace FrostFS.SDK.ModelsV2;
|
||||
|
||||
public class Status
|
||||
{
|
||||
public StatusCode Code { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
public Status(StatusCode code, string? message = null)
|
||||
{
|
||||
Code = code;
|
||||
Message = message ?? string.Empty;
|
||||
}
|
||||
|
||||
public bool IsSuccess()
|
||||
{
|
||||
return Code == StatusCode.Success;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Response status: {Code}. Message: {Message}.";
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue