• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H
18 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H
19 
20 #include <grpc/support/port_platform.h>
21 
22 #include <functional>
23 #include <map>
24 #include <vector>
25 
26 #include "absl/strings/string_view.h"
27 
28 #include <grpc/grpc.h>
29 
30 #include "src/core/ext/filters/client_channel/service_config.h"
31 #include "src/core/ext/filters/client_channel/service_config_parser.h"
32 #include "src/core/lib/channel/channel_stack.h"
33 #include "src/core/lib/gprpp/arena.h"
34 #include "src/core/lib/gprpp/ref_counted.h"
35 #include "src/core/lib/gprpp/ref_counted_ptr.h"
36 #include "src/core/lib/transport/metadata_batch.h"
37 
38 // Channel arg key for ConfigSelector.
39 #define GRPC_ARG_CONFIG_SELECTOR "grpc.internal.config_selector"
40 
41 namespace grpc_core {
42 
43 // Internal API used to allow resolver implementations to override
44 // MethodConfig and provide input to LB policies on a per-call basis.
45 class ConfigSelector : public RefCounted<ConfigSelector> {
46  public:
47   struct GetCallConfigArgs {
48     grpc_slice* path;
49     grpc_metadata_batch* initial_metadata;
50     Arena* arena;
51   };
52 
53   struct CallConfig {
54     // Can be set to indicate the call should be failed.
55     grpc_error_handle error = GRPC_ERROR_NONE;
56     // The per-method parsed configs that will be passed to
57     // ServiceConfigCallData.
58     const ServiceConfigParser::ParsedConfigVector* method_configs = nullptr;
59     // A ref to the service config that contains method_configs, held by
60     // the call to ensure that method_configs lives long enough.
61     RefCountedPtr<ServiceConfig> service_config;
62     // Call attributes that will be accessible to LB policy implementations.
63     std::map<const char*, absl::string_view> call_attributes;
64     // A callback that, if set, will be invoked when the call is
65     // committed (i.e., when we know that we will never again need to
66     // ask the picker for a subchannel for this call).
67     std::function<void()> on_call_committed;
68   };
69 
70   ~ConfigSelector() override = default;
71 
72   virtual const char* name() const = 0;
73 
74   // Will be called only if the two objects have the same name, so
75   // subclasses can be free to safely down-cast the argument.
76   virtual bool Equals(const ConfigSelector* other) const = 0;
77 
Equals(const ConfigSelector * cs1,const ConfigSelector * cs2)78   static bool Equals(const ConfigSelector* cs1, const ConfigSelector* cs2) {
79     if (cs1 == nullptr) return cs2 == nullptr;
80     if (cs2 == nullptr) return false;
81     if (strcmp(cs1->name(), cs2->name()) != 0) return false;
82     return cs1->Equals(cs2);
83   }
84 
85   // The channel will call this when the resolver returns a new ConfigSelector
86   // to determine what set of dynamic filters will be configured.
GetFilters()87   virtual std::vector<const grpc_channel_filter*> GetFilters() { return {}; }
88 
89   // Modifies channel args to be passed to the dynamic filter stack.
90   // Takes ownership of argument.  Caller takes ownership of result.
ModifyChannelArgs(grpc_channel_args * args)91   virtual grpc_channel_args* ModifyChannelArgs(grpc_channel_args* args) {
92     return args;
93   }
94 
95   virtual CallConfig GetCallConfig(GetCallConfigArgs args) = 0;
96 
97   grpc_arg MakeChannelArg() const;
98   static RefCountedPtr<ConfigSelector> GetFromChannelArgs(
99       const grpc_channel_args& args);
100 };
101 
102 // Default ConfigSelector that gets the MethodConfig from the service config.
103 class DefaultConfigSelector : public ConfigSelector {
104  public:
DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config)105   explicit DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config)
106       : service_config_(std::move(service_config)) {
107     // The client channel code ensures that this will never be null.
108     // If neither the resolver nor the client application provide a
109     // config, a default empty config will be used.
110     GPR_DEBUG_ASSERT(service_config_ != nullptr);
111   }
112 
name()113   const char* name() const override { return "default"; }
114 
115   // Only comparing the ConfigSelector itself, not the underlying
116   // service config, so we always return true.
Equals(const ConfigSelector *)117   bool Equals(const ConfigSelector* /*other*/) const override { return true; }
118 
GetCallConfig(GetCallConfigArgs args)119   CallConfig GetCallConfig(GetCallConfigArgs args) override {
120     CallConfig call_config;
121     call_config.method_configs =
122         service_config_->GetMethodParsedConfigVector(*args.path);
123     call_config.service_config = service_config_;
124     return call_config;
125   }
126 
127  private:
128   RefCountedPtr<ServiceConfig> service_config_;
129 };
130 
131 }  // namespace grpc_core
132 
133 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H */
134