userver: /home/antonyzhilin/arcadia/taxi/uservices/userver/libraries/grpc-protovalidate/src/grpc-protovalidate/client/middleware.cpp Source File
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
middleware.cpp
1#include <grpc-protovalidate/client/middleware.hpp>
2
3#include <google/protobuf/arena.h>
4
5#include <userver/grpc-protovalidate/client/exceptions.hpp>
6#include <userver/logging/log.hpp>
7
8#include <grpc-protovalidate/impl/utils.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace grpc_protovalidate::client {
13
14const ValidationSettings& Settings::Get(std::string_view method_name) const {
15 auto it = per_method.find(method_name);
16 return it != per_method.end() ? it->second : global;
17}
18
19Middleware::Middleware(const Settings& settings)
20 : settings_(settings), validator_factory_(grpc_protovalidate::impl::CreateProtoValidatorFactory()) {}
21
22Middleware::~Middleware() = default;
23
24void Middleware::PostRecvMessage(
25 ugrpc::client::MiddlewareCallContext& context,
26 const google::protobuf::Message& message
27) const {
28 const auto& settings = settings_.Get(context.GetCallName());
29 google::protobuf::Arena arena;
30
31 auto validator = validator_factory_->NewValidator(&arena, settings.fail_fast);
32 auto result = validator.Validate(message);
33
34 if (!result.ok()) {
35 // Usually that means some CEL expression in a proto file can not be
36 // parsed or evaluated.
37 LOG_ERROR() << "Validator internal error (check response constraints in the proto file): " << result.status();
38 throw ValidatorError(context.GetCallName());
39 } else if (result.value().violations_size() > 0) {
40 for (const auto& violation : result.value().violations()) {
41 LOG_ERROR() << "Response constraint violation: " << violation.proto();
42 }
43
44 throw ResponseError(context.GetCallName(), std::move(result).value());
45 } else {
46 LOG_DEBUG() << "Response is valid";
47 }
48}
49
50} // namespace grpc_protovalidate::client
51
52USERVER_NAMESPACE_END