1/*
2 *
3 * Copyright 2018 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19#ifndef GRPCPP_IMPL_CODEGEN_SERVER_INTERCEPTOR_H
20#define GRPCPP_IMPL_CODEGEN_SERVER_INTERCEPTOR_H
21
22#include <atomic>
23#include <vector>
24
25#include <grpcpp/impl/codegen/interceptor.h>
26#include <grpcpp/impl/codegen/rpc_method.h>
27#include <grpcpp/impl/codegen/string_ref.h>
28
29namespace grpc_impl {
30class ServerContextBase;
31} // namespace grpc_impl
32
33namespace grpc {
34
35namespace internal {
36class InterceptorBatchMethodsImpl;
37}
38
39namespace experimental {
40class ServerRpcInfo;
41
42// A factory interface for creation of server interceptors. A vector of
43// factories can be provided to ServerBuilder which will be used to create a new
44// vector of server interceptors per RPC. Server interceptor authors should
45// create a subclass of ServerInterceptorFactorInterface which creates objects
46// of their interceptors.
47class ServerInterceptorFactoryInterface {
48 public:
49 virtual ~ServerInterceptorFactoryInterface() {}
50 // Returns a pointer to an Interceptor object on successful creation, nullptr
51 // otherwise. If nullptr is returned, this server interceptor factory is
52 // ignored for the purposes of that RPC.
53 virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0;
54};
55
56/// ServerRpcInfo represents the state of a particular RPC as it
57/// appears to an interceptor. It is created and owned by the library and
58/// passed to the CreateServerInterceptor method of the application's
59/// ServerInterceptorFactoryInterface implementation
60class ServerRpcInfo {
61 public:
62 /// Type categorizes RPCs by unary or streaming type
63 enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING };
64
65 ~ServerRpcInfo() {}
66
67 // Delete all copy and move constructors and assignments
68 ServerRpcInfo(const ServerRpcInfo&) = delete;
69 ServerRpcInfo& operator=(const ServerRpcInfo&) = delete;
70 ServerRpcInfo(ServerRpcInfo&&) = delete;
71 ServerRpcInfo& operator=(ServerRpcInfo&&) = delete;
72
73 // Getter methods
74
75 /// Return the fully-specified method name
76 const char* method() const { return method_; }
77
78 /// Return the type of the RPC (unary or a streaming flavor)
79 Type type() const { return type_; }
80
81 /// Return a pointer to the underlying ServerContext structure associated
82 /// with the RPC to support features that apply to it
83 grpc_impl::ServerContextBase* server_context() { return ctx_; }
84
85 private:
86 static_assert(Type::UNARY ==
87 static_cast<Type>(internal::RpcMethod::NORMAL_RPC),
88 "violated expectation about Type enum");
89 static_assert(Type::CLIENT_STREAMING ==
90 static_cast<Type>(internal::RpcMethod::CLIENT_STREAMING),
91 "violated expectation about Type enum");
92 static_assert(Type::SERVER_STREAMING ==
93 static_cast<Type>(internal::RpcMethod::SERVER_STREAMING),
94 "violated expectation about Type enum");
95 static_assert(Type::BIDI_STREAMING ==
96 static_cast<Type>(internal::RpcMethod::BIDI_STREAMING),
97 "violated expectation about Type enum");
98
99 ServerRpcInfo(grpc_impl::ServerContextBase* ctx, const char* method,
100 internal::RpcMethod::RpcType type)
101 : ctx_(ctx), method_(method), type_(static_cast<Type>(type)) {}
102
103 // Runs interceptor at pos \a pos.
104 void RunInterceptor(
105 experimental::InterceptorBatchMethods* interceptor_methods, size_t pos) {
106 GPR_CODEGEN_ASSERT(pos < interceptors_.size());
107 interceptors_[pos]->Intercept(methods: interceptor_methods);
108 }
109
110 void RegisterInterceptors(
111 const std::vector<
112 std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>&
113 creators) {
114 for (const auto& creator : creators) {
115 auto* interceptor = creator->CreateServerInterceptor(info: this);
116 if (interceptor != nullptr) {
117 interceptors_.push_back(
118 x: std::unique_ptr<experimental::Interceptor>(interceptor));
119 }
120 }
121 }
122
123 void Ref() { ref_.fetch_add(i: 1, m: std::memory_order_relaxed); }
124 void Unref() {
125 if (GPR_UNLIKELY(ref_.fetch_sub(1, std::memory_order_acq_rel) == 1)) {
126 delete this;
127 }
128 }
129
130 grpc_impl::ServerContextBase* ctx_ = nullptr;
131 const char* method_ = nullptr;
132 const Type type_;
133 std::atomic<intptr_t> ref_{1};
134 std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
135
136 friend class internal::InterceptorBatchMethodsImpl;
137 friend class grpc_impl::ServerContextBase;
138};
139
140} // namespace experimental
141} // namespace grpc
142
143#endif // GRPCPP_IMPL_CODEGEN_SERVER_INTERCEPTOR_H
144

source code of include/grpcpp/impl/codegen/server_interceptor.h