[#1] Add response checker
All checks were successful
DCO / DCO (pull_request) Successful in 40s
All checks were successful
DCO / DCO (pull_request) Successful in 40s
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.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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
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