8875a28bf3245956012096fa3244151e0a1ff876
[platform/upstream/grpc.git] / include / grpcpp / impl / codegen / server_interceptor.h
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
29 namespace grpc {
30
31 class ServerContext;
32
33 namespace internal {
34 class InterceptorBatchMethodsImpl;
35 }
36
37 namespace experimental {
38 class ServerRpcInfo;
39
40 // A factory interface for creation of server interceptors. A vector of
41 // factories can be provided to ServerBuilder which will be used to create a new
42 // vector of server interceptors per RPC. Server interceptor authors should
43 // create a subclass of ServerInterceptorFactorInterface which creates objects
44 // of their interceptors.
45 class ServerInterceptorFactoryInterface {
46  public:
47   virtual ~ServerInterceptorFactoryInterface() {}
48   // Returns a pointer to an Interceptor object on successful creation, nullptr
49   // otherwise. If nullptr is returned, this server interceptor factory is
50   // ignored for the purposes of that RPC.
51   virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0;
52 };
53
54 /// ServerRpcInfo represents the state of a particular RPC as it
55 /// appears to an interceptor. It is created and owned by the library and
56 /// passed to the CreateServerInterceptor method of the application's
57 /// ServerInterceptorFactoryInterface implementation
58 class ServerRpcInfo {
59  public:
60   /// Type categorizes RPCs by unary or streaming type
61   enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING };
62
63   ~ServerRpcInfo() {}
64
65   // Delete all copy and move constructors and assignments
66   ServerRpcInfo(const ServerRpcInfo&) = delete;
67   ServerRpcInfo& operator=(const ServerRpcInfo&) = delete;
68   ServerRpcInfo(ServerRpcInfo&&) = delete;
69   ServerRpcInfo& operator=(ServerRpcInfo&&) = delete;
70
71   // Getter methods
72
73   /// Return the fully-specified method name
74   const char* method() const { return method_; }
75
76   /// Return the type of the RPC (unary or a streaming flavor)
77   Type type() const { return type_; }
78
79   /// Return a pointer to the underlying ServerContext structure associated
80   /// with the RPC to support features that apply to it
81   grpc::ServerContext* server_context() { return ctx_; }
82
83  private:
84   static_assert(Type::UNARY ==
85                     static_cast<Type>(internal::RpcMethod::NORMAL_RPC),
86                 "violated expectation about Type enum");
87   static_assert(Type::CLIENT_STREAMING ==
88                     static_cast<Type>(internal::RpcMethod::CLIENT_STREAMING),
89                 "violated expectation about Type enum");
90   static_assert(Type::SERVER_STREAMING ==
91                     static_cast<Type>(internal::RpcMethod::SERVER_STREAMING),
92                 "violated expectation about Type enum");
93   static_assert(Type::BIDI_STREAMING ==
94                     static_cast<Type>(internal::RpcMethod::BIDI_STREAMING),
95                 "violated expectation about Type enum");
96
97   ServerRpcInfo(grpc::ServerContext* ctx, const char* method,
98                 internal::RpcMethod::RpcType type)
99       : ctx_(ctx), method_(method), type_(static_cast<Type>(type)) {
100     ref_.store(1);
101   }
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(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(this);
116       if (interceptor != nullptr) {
117         interceptors_.push_back(
118             std::unique_ptr<experimental::Interceptor>(interceptor));
119       }
120     }
121   }
122
123   void Ref() { ref_++; }
124   void Unref() {
125     if (--ref_ == 0) {
126       delete this;
127     }
128   }
129
130   grpc::ServerContext* ctx_ = nullptr;
131   const char* method_ = nullptr;
132   const Type type_;
133   std::atomic_int ref_;
134   std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
135
136   friend class internal::InterceptorBatchMethodsImpl;
137   friend class grpc::ServerContext;
138 };
139
140 }  // namespace experimental
141 }  // namespace grpc
142
143 #endif  // GRPCPP_IMPL_CODEGEN_SERVER_INTERCEPTOR_H