GRPC C++  1.26.0
client_interceptor.h
Go to the documentation of this file.
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_CLIENT_INTERCEPTOR_H
20 #define GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H
21 
22 #include <memory>
23 #include <vector>
24 
28 
29 namespace grpc_impl {
30 
31 class Channel;
32 class ClientContext;
33 } // namespace grpc_impl
34 
35 namespace grpc {
36 
37 namespace internal {
38 class InterceptorBatchMethodsImpl;
39 }
40 
41 namespace experimental {
42 class ClientRpcInfo;
43 
44 // A factory interface for creation of client interceptors. A vector of
45 // factories can be provided at channel creation which will be used to create a
46 // new vector of client interceptors per RPC. Client interceptor authors should
47 // create a subclass of ClientInterceptorFactorInterface which creates objects
48 // of their interceptors.
50  public:
52  // Returns a pointer to an Interceptor object on successful creation, nullptr
53  // otherwise. If nullptr is returned, this server interceptor factory is
54  // ignored for the purposes of that RPC.
55  virtual Interceptor* CreateClientInterceptor(ClientRpcInfo* info) = 0;
56 };
57 } // namespace experimental
58 
59 namespace internal {
62 }
63 
68 namespace experimental {
70  public:
71  // TODO(yashykt): Stop default-constructing ClientRpcInfo and remove UNKNOWN
72  // from the list of possible Types.
74  enum class Type {
75  UNARY,
76  CLIENT_STREAMING,
77  SERVER_STREAMING,
78  BIDI_STREAMING,
79  UNKNOWN // UNKNOWN is not API and will be removed later
80  };
81 
83 
84  // Delete copy constructor but allow default move constructor
85  ClientRpcInfo(const ClientRpcInfo&) = delete;
86  ClientRpcInfo(ClientRpcInfo&&) = default;
87 
88  // Getter methods
89 
91  const char* method() const { return method_; }
92 
94  ChannelInterface* channel() { return channel_; }
95 
99 
101  Type type() const { return type_; }
102 
103  private:
104  static_assert(Type::UNARY ==
105  static_cast<Type>(internal::RpcMethod::NORMAL_RPC),
106  "violated expectation about Type enum");
107  static_assert(Type::CLIENT_STREAMING ==
108  static_cast<Type>(internal::RpcMethod::CLIENT_STREAMING),
109  "violated expectation about Type enum");
110  static_assert(Type::SERVER_STREAMING ==
111  static_cast<Type>(internal::RpcMethod::SERVER_STREAMING),
112  "violated expectation about Type enum");
113  static_assert(Type::BIDI_STREAMING ==
114  static_cast<Type>(internal::RpcMethod::BIDI_STREAMING),
115  "violated expectation about Type enum");
116 
117  // Default constructor should only be used by ClientContext
118  ClientRpcInfo() = default;
119 
120  // Constructor will only be called from ClientContext
122  internal::RpcMethod::RpcType type, const char* method,
123  grpc::ChannelInterface* channel)
124  : ctx_(ctx),
125  type_(static_cast<Type>(type)),
126  method_(method),
127  channel_(channel) {}
128 
129  // Move assignment should only be used by ClientContext
130  // TODO(yashykt): Delete move assignment
131  ClientRpcInfo& operator=(ClientRpcInfo&&) = default;
132 
133  // Runs interceptor at pos \a pos.
134  void RunInterceptor(
135  experimental::InterceptorBatchMethods* interceptor_methods, size_t pos) {
136  GPR_CODEGEN_ASSERT(pos < interceptors_.size());
137  interceptors_[pos]->Intercept(interceptor_methods);
138  }
139 
140  void RegisterInterceptors(
141  const std::vector<std::unique_ptr<
143  size_t interceptor_pos) {
144  if (interceptor_pos > creators.size()) {
145  // No interceptors to register
146  return;
147  }
148  // NOTE: The following is not a range-based for loop because it will only
149  // iterate over a portion of the creators vector.
150  for (auto it = creators.begin() + interceptor_pos; it != creators.end();
151  ++it) {
152  auto* interceptor = (*it)->CreateClientInterceptor(this);
153  if (interceptor != nullptr) {
154  interceptors_.push_back(
155  std::unique_ptr<experimental::Interceptor>(interceptor));
156  }
157  }
159  interceptors_.push_back(std::unique_ptr<experimental::Interceptor>(
161  ->CreateClientInterceptor(this)));
162  }
163  }
164 
165  grpc_impl::ClientContext* ctx_ = nullptr;
166  // TODO(yashykt): make type_ const once move-assignment is deleted
167  Type type_{Type::UNKNOWN};
168  const char* method_ = nullptr;
169  grpc::ChannelInterface* channel_ = nullptr;
170  std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
171  bool hijacked_ = false;
172  size_t hijacked_interceptor_ = 0;
173 
176 };
177 
178 // PLEASE DO NOT USE THIS. ALWAYS PREFER PER CHANNEL INTERCEPTORS OVER A GLOBAL
179 // INTERCEPTOR. IF USAGE IS ABSOLUTELY NECESSARY, PLEASE READ THE SAFETY NOTES.
180 // Registers a global client interceptor factory object, which is used for all
181 // RPCs made in this process. The application is responsible for maintaining the
182 // life of the object while gRPC operations are in progress. The global
183 // interceptor factory should only be registered once at the start of the
184 // process before any gRPC operations have begun.
187 
188 // For testing purposes only
190 
191 } // namespace experimental
192 } // namespace grpc
193 
194 #endif // GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H
::grpc_impl::ClientContext ClientContext
Definition: client_context.h:26
#define GPR_CODEGEN_ASSERT(x)
Codegen specific version of GPR_ASSERT.
Definition: core_codegen_interface.h:146
Class that is passed as an argument to the Intercept method of the application&#39;s Interceptor interfac...
Definition: interceptor.h:91
~ClientRpcInfo()
Definition: client_interceptor.h:82
void RegisterGlobalClientInterceptorFactory(ClientInterceptorFactoryInterface *factory)
ChannelInterface * channel()
Return a pointer to the channel on which the RPC is being sent.
Definition: client_interceptor.h:94
virtual ~ClientInterceptorFactoryInterface()
Definition: client_interceptor.h:51
RpcType
Definition: rpc_method.h:31
Type type() const
Return the type of the RPC (unary or a streaming flavor)
Definition: client_interceptor.h:101
::grpc_impl::Channel Channel
Definition: channel.h:26
const char * method() const
Return the fully-specified method name.
Definition: client_interceptor.h:91
This header provides an object that reads bytes directly from a grpc::ByteBuffer, via the ZeroCopyInp...
Definition: alarm.h:24
Interface for an interceptor.
Definition: interceptor.h:215
Codegen interface for grpc::Channel.
Definition: channel_interface.h:74
Definition: interceptor_common.h:36
An Alarm posts the user-provided tag to its associated completion queue or invokes the user-provided ...
Definition: alarm_impl.h:33
void TestOnlyResetGlobalClientInterceptorFactory()
experimental::ClientInterceptorFactoryInterface * g_global_client_interceptor_factory
A ClientContext allows the person implementing a service client to:
Definition: client_context_impl.h:184
grpc_impl::ClientContext * client_context()
Return a pointer to the underlying ClientContext structure associated with the RPC to support feature...
Definition: client_interceptor.h:98
Unknown error.
Definition: status_code_enum.h:35
Type
Type categorizes RPCs by unary or streaming type.
Definition: client_interceptor.h:74
Definition: client_interceptor.h:69