[#1] Add response checker

Signed-off-by: Ivan Pchelintsev <i.pchelintsev@yadro.com>
This commit is contained in:
Ivan Pchelintsev 2024-05-22 12:28:06 +03:00
parent 8cacbcc8e9
commit ae3fc419a4
6 changed files with 91 additions and 10 deletions

View 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);
}
}

View file

@ -18,6 +18,7 @@ public partial class Client
request.AddMetaHeader(); request.AddMetaHeader();
request.Sign(_key); request.Sign(_key);
var response = await _containerServiceClient.GetAsync(request); var response = await _containerServiceClient.GetAsync(request);
Verifier.CheckResponse(response);
return response.Body.Container.ToModel(); return response.Body.Container.ToModel();
} }
@ -33,6 +34,7 @@ public partial class Client
request.AddMetaHeader(); request.AddMetaHeader();
request.Sign(_key); request.Sign(_key);
var response = await _containerServiceClient.ListAsync(request); var response = await _containerServiceClient.ListAsync(request);
Verifier.CheckResponse(response);
foreach (var cid in response.Body.ContainerIds) foreach (var cid in response.Body.ContainerIds)
{ {
yield return ContainerId.FromHash(cid.Value.ToByteArray()); yield return ContainerId.FromHash(cid.Value.ToByteArray());
@ -55,7 +57,7 @@ public partial class Client
request.AddMetaHeader(); request.AddMetaHeader();
request.Sign(_key); request.Sign(_key);
var response = await _containerServiceClient.PutAsync(request); var response = await _containerServiceClient.PutAsync(request);
RequestVerifier.ProcessResponse(response); Verifier.CheckResponse(response);
return ContainerId.FromHash(response.Body.ContainerId.Value.ToByteArray()); return ContainerId.FromHash(response.Body.ContainerId.Value.ToByteArray());
} }
@ -71,6 +73,7 @@ public partial class Client
}; };
request.AddMetaHeader(); request.AddMetaHeader();
request.Sign(_key); request.Sign(_key);
await _containerServiceClient.DeleteAsync(request); var response = await _containerServiceClient.DeleteAsync(request);
Verifier.CheckResponse(response);
} }
} }

View file

@ -27,6 +27,7 @@ public partial class Client
request.AddMetaHeader(); request.AddMetaHeader();
request.Sign(_key); request.Sign(_key);
var response = await _objectServiceClient.HeadAsync(request); var response = await _objectServiceClient.HeadAsync(request);
Verifier.CheckResponse(response);
return response.Body.Header.Header.ToModel(); return response.Body.Header.Header.ToModel();
} }
@ -55,8 +56,8 @@ public partial class Client
); );
request.Sign(_key); request.Sign(_key);
var response = await GetObject(request); var obj = await GetObject(request);
return response.ToModel(); return obj.ToModel();
} }
private async Task<Object.Object> GetObject(GetRequest request) private async Task<Object.Object> GetObject(GetRequest request)
@ -146,6 +147,7 @@ public partial class Client
} }
var response = await stream.Close(); var response = await stream.Close();
Verifier.CheckResponse(response);
return ObjectId.FromHash(response.Body.ObjectId.Value.ToByteArray()); return ObjectId.FromHash(response.Body.ObjectId.Value.ToByteArray());
} }
@ -176,7 +178,8 @@ public partial class Client
}; };
request.AddMetaHeader(); request.AddMetaHeader();
request.Sign(_key); 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) public async IAsyncEnumerable<ObjectId> SearchObjectsAsync(ContainerId cid, params ObjectFilter[] filters)
@ -245,6 +248,7 @@ internal class ObjectReader : IDisposable
} }
var response = Call.ResponseStream.Current; var response = Call.ResponseStream.Current;
Verifier.CheckResponse(response);
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Init) if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Init)
throw new InvalidOperationException("unexpect message type"); throw new InvalidOperationException("unexpect message type");
return new Object.Object return new Object.Object
@ -262,6 +266,7 @@ internal class ObjectReader : IDisposable
} }
var response = Call.ResponseStream.Current; var response = Call.ResponseStream.Current;
Verifier.CheckResponse(response);
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Chunk) if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Chunk)
throw new InvalidOperationException("unexpect message type"); throw new InvalidOperationException("unexpect message type");
return response.Body.Chunk.ToByteArray(); return response.Body.Chunk.ToByteArray();
@ -311,6 +316,7 @@ internal class SearchReader : IDisposable
} }
var response = Call.ResponseStream.Current; var response = Call.ResponseStream.Current;
Verifier.CheckResponse(response);
return response.Body?.IdList.ToList(); return response.Body?.IdList.ToList();
} }

View file

@ -1,5 +1,6 @@
using System.Security.Cryptography; using System.Security.Cryptography;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography; using FrostFS.SDK.Cryptography;
using FrostFS.Session; using FrostFS.Session;
using Google.Protobuf; using Google.Protobuf;
@ -9,8 +10,9 @@ using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers; using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Math; using Org.BouncyCastle.Math;
namespace FrostFS.SDK.ClientV2 { namespace FrostFS.SDK.ClientV2
public static class RequestVerifier {
public static class Verifier
{ {
public const int RFC6979SignatureSize = 64; public const int RFC6979SignatureSize = 64;
@ -73,11 +75,15 @@ namespace FrostFS.SDK.ClientV2 {
return VerifyMatryoskaLevel(message.GetBody(), message.GetMetaHeader(), message.GetVerificationHeader()); 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()) if (!resp.Verify())
throw new FormatException($"invalid response, type={resp.GetType()}"); throw new FormatException($"invalid response, type={resp.GetType()}");
var status = resp.MetaHeader.Status.ToModel();
if (!status.IsSuccess())
{
throw new ApplicationException(status.ToString());
}
} }
} }
} }

View 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
}

View 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}.";
}
}