userver: userver/ugrpc/server/call.hpp Source File
Loading...
Searching...
No Matches
call.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/ugrpc/server/call.hpp
4/// @brief @copybrief ugrpc::server::CallAnyBase
5
6#include <google/protobuf/message.h>
7#include <grpcpp/server_context.h>
8
9#include <userver/ugrpc/impl/internal_tag_fwd.hpp>
10#include <userver/ugrpc/impl/span.hpp>
11#include <userver/ugrpc/impl/statistics_scope.hpp>
12#include <userver/ugrpc/server/impl/call_params.hpp>
13#include <userver/ugrpc/server/middlewares/fwd.hpp>
14
15USERVER_NAMESPACE_BEGIN
16
17namespace ugrpc::server {
18
19/// @brief RPCs kinds
20enum class CallKind {
21 kUnaryCall,
22 kRequestStream,
23 kResponseStream,
24 kBidirectionalStream,
25};
26
27/// @brief A non-typed base class for any gRPC call
29public:
30 /// @brief Complete the RPC with an error
31 ///
32 /// `Finish` must not be called multiple times for the same RPC.
33 ///
34 /// @param status error details
35 /// @throws ugrpc::server::RpcError on an RPC error
36 /// @see @ref IsFinished
37 virtual void FinishWithError(const grpc::Status& status) = 0;
38
39 /// @returns the `ServerContext` used for this RPC
40 /// @note Initial server metadata is not currently supported
41 /// @note Trailing metadata, if any, must be set before the `Finish` call
42 grpc::ServerContext& GetContext() { return params_.context; }
43
44 /// @brief Name of the RPC in the format `full.path.ServiceName/MethodName`
45 std::string_view GetCallName() const { return params_.call_name; }
46
47 /// @brief Get name of gRPC service
49
50 /// @brief Get name of called gRPC method
52
53 /// @brief Get the span of the current RPC. Span's lifetime covers the
54 /// `Handle` call of the outermost @ref MiddlewareBase "middleware".
55 tracing::Span& GetSpan() { return params_.call_span; }
56
57 /// @brief Get RPCs kind of method
58 CallKind GetCallKind() const { return call_kind_; }
59
60 /// @brief Returns call context for storing per-call custom data
61 ///
62 /// The context can be used to pass data from server middleware to client
63 /// handler or from one middleware to another one.
64 ///
65 /// ## Example usage:
66 ///
67 /// In authentication middleware:
68 ///
69 /// @code
70 /// if (password_is_correct) {
71 /// // Username is authenticated, set it in per-call storage context
72 /// ctx.GetCall().GetStorageContext().Emplace(kAuthUsername, username);
73 /// }
74 /// @endcode
75 ///
76 /// In client handler:
77 ///
78 /// @code
79 /// const auto& username = rpc.GetStorageContext().Get(kAuthUsername);
80 /// auto msg = fmt::format("Hello, {}!", username);
81 /// @endcode
82 utils::AnyStorage<StorageContext>& GetStorageContext() { return params_.storage_context; }
83
84 /// @brief Useful for generic error reporting via @ref FinishWithError
85 virtual bool IsFinished() const = 0;
86
87 /// @brief Set a custom call name for metric labels
88 void SetMetricsCallName(std::string_view call_name);
89
90 /// @cond
91 // For internal use only
92 CallAnyBase(utils::impl::InternalTag, impl::CallParams&& params, CallKind call_kind)
93 : params_(std::move(params)), call_kind_(call_kind) {}
94
95 // For internal use only
96 ugrpc::impl::RpcStatisticsScope& GetStatistics(ugrpc::impl::InternalTag);
97
98 // For internal use only
99 void RunMiddlewarePipeline(utils::impl::InternalTag, MiddlewareCallContext& md_call_context);
100 /// @endcond
101
102protected:
103 ugrpc::impl::RpcStatisticsScope& GetStatistics() { return params_.statistics; }
104
105 logging::LoggerRef AccessTskvLogger() { return params_.access_tskv_logger; }
106
107 void LogFinish(grpc::Status status) const;
108
109 void ApplyRequestHook(google::protobuf::Message* request);
110
111 void ApplyResponseHook(google::protobuf::Message* response);
112
113private:
114 impl::CallParams params_;
115 CallKind call_kind_;
116 MiddlewareCallContext* middleware_call_context_{nullptr};
117};
118
119} // namespace ugrpc::server
120
121USERVER_NAMESPACE_END