1/*
2 *
3 * Copyright 2015 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_SUPPORT_SERVER_INTERCEPTOR_H
20#define GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H
21
22#include <atomic>
23#include <vector>
24
25#include <grpcpp/impl/rpc_method.h>
26#include <grpcpp/support/interceptor.h>
27#include <grpcpp/support/string_ref.h>
28
29namespace grpc {
30class ServerContextBase;
31namespace internal {
32class InterceptorBatchMethodsImpl;
33}
34
35namespace experimental {
36class ServerRpcInfo;
37
38// A factory interface for creation of server interceptors. A vector of
39// factories can be provided to ServerBuilder which will be used to create a new
40// vector of server interceptors per RPC. Server interceptor authors should
41// create a subclass of ServerInterceptorFactorInterface which creates objects
42// of their interceptors.
43class ServerInterceptorFactoryInterface {
44 public:
45 virtual ~ServerInterceptorFactoryInterface() {}
46 // Returns a pointer to an Interceptor object on successful creation, nullptr
47 // otherwise. If nullptr is returned, this server interceptor factory is
48 // ignored for the purposes of that RPC.
49 virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0;
50};
51
52/// ServerRpcInfo represents the state of a particular RPC as it
53/// appears to an interceptor. It is created and owned by the library and
54/// passed to the CreateServerInterceptor method of the application's
55/// ServerInterceptorFactoryInterface implementation
56class ServerRpcInfo {
57 public:
58 /// Type categorizes RPCs by unary or streaming type
59 enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING };
60
61 ~ServerRpcInfo() {}
62
63 // Delete all copy and move constructors and assignments
64 ServerRpcInfo(const ServerRpcInfo&) = delete;
65 ServerRpcInfo& operator=(const ServerRpcInfo&) = delete;
66 ServerRpcInfo(ServerRpcInfo&&) = delete;
67 ServerRpcInfo& operator=(ServerRpcInfo&&) = delete;
68
69 // Getter methods
70
71 /// Return the fully-specified method name
72 const char* method() const { return method_; }
73
74 /// Return the type of the RPC (unary or a streaming flavor)
75 Type type() const { return type_; }
76
77 /// Return a pointer to the underlying ServerContext structure associated
78 /// with the RPC to support features that apply to it
79 ServerContextBase* server_context() { return ctx_; }
80
81 private:
82 static_assert(Type::UNARY ==
83 static_cast<Type>(internal::RpcMethod::NORMAL_RPC),
84 "violated expectation about Type enum");
85 static_assert(Type::CLIENT_STREAMING ==
86 static_cast<Type>(internal::RpcMethod::CLIENT_STREAMING),
87 "violated expectation about Type enum");
88 static_assert(Type::SERVER_STREAMING ==
89 static_cast<Type>(internal::RpcMethod::SERVER_STREAMING),
90 "violated expectation about Type enum");
91 static_assert(Type::BIDI_STREAMING ==
92 static_cast<Type>(internal::RpcMethod::BIDI_STREAMING),
93 "violated expectation about Type enum");
94
95 ServerRpcInfo(ServerContextBase* ctx, const char* method,
96 internal::RpcMethod::RpcType type)
97 : ctx_(ctx), method_(method), type_(static_cast<Type>(type)) {}
98
99 // Runs interceptor at pos \a pos.
100 void RunInterceptor(
101 experimental::InterceptorBatchMethods* interceptor_methods, size_t pos) {
102 GPR_CODEGEN_ASSERT(pos < interceptors_.size());
103 interceptors_[pos]->Intercept(methods: interceptor_methods);
104 }
105
106 void RegisterInterceptors(
107 const std::vector<
108 std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>&
109 creators) {
110 for (const auto& creator : creators) {
111 auto* interceptor = creator->CreateServerInterceptor(info: this);
112 if (interceptor != nullptr) {
113 interceptors_.push_back(
114 x: std::unique_ptr<experimental::Interceptor>(interceptor));
115 }
116 }
117 }
118
119 void Ref() { ref_.fetch_add(i: 1, m: std::memory_order_relaxed); }
120 void Unref() {
121 if (GPR_UNLIKELY(ref_.fetch_sub(1, std::memory_order_acq_rel) == 1)) {
122 delete this;
123 }
124 }
125
126 ServerContextBase* ctx_ = nullptr;
127 const char* method_ = nullptr;
128 const Type type_;
129 std::atomic<intptr_t> ref_{1};
130 std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
131
132 friend class internal::InterceptorBatchMethodsImpl;
133 friend class grpc::ServerContextBase;
134};
135
136} // namespace experimental
137} // namespace grpc
138
139#endif // GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H
140

source code of include/grpcpp/support/server_interceptor.h