Imported Upstream version 1.33.1
[platform/upstream/grpc.git] / src / core / ext / filters / client_channel / config_selector.h
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
25 #include "absl/strings/string_view.h"
26
27 #include <grpc/impl/codegen/grpc_types.h>
28 #include <grpc/impl/codegen/slice.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/gprpp/arena.h"
33 #include "src/core/lib/gprpp/ref_counted.h"
34 #include "src/core/lib/gprpp/ref_counted_ptr.h"
35 #include "src/core/lib/transport/metadata_batch.h"
36
37 // Channel arg key for ConfigSelector.
38 #define GRPC_ARG_CONFIG_SELECTOR "grpc.internal.config_selector"
39
40 namespace grpc_core {
41
42 // Internal API used to allow resolver implementations to override
43 // MethodConfig and provide input to LB policies on a per-call basis.
44 class ConfigSelector : public RefCounted<ConfigSelector> {
45  public:
46   struct GetCallConfigArgs {
47     grpc_slice* path;
48     grpc_metadata_batch* initial_metadata;
49     Arena* arena;
50   };
51
52   struct CallConfig {
53     // Can be set to indicate the call should be failed.
54     grpc_error* error = GRPC_ERROR_NONE;
55     // The per-method parsed configs that will be passed to
56     // ServiceConfigCallData.
57     const ServiceConfigParser::ParsedConfigVector* method_configs = nullptr;
58     // A ref to the service config that contains method_configs, held by
59     // the call to ensure that method_configs lives long enough.
60     RefCountedPtr<ServiceConfig> service_config;
61     // Call attributes that will be accessible to LB policy implementations.
62     std::map<const char*, absl::string_view> call_attributes;
63     // A callback that, if set, will be invoked when the call is
64     // committed (i.e., when we know that we will never again need to
65     // ask the picker for a subchannel for this call).
66     std::function<void()> on_call_committed;
67   };
68
69   virtual ~ConfigSelector() = default;
70
71   virtual const char* name() const = 0;
72
73   // Will be called only if the two objects have the same name, so
74   // subclasses can be free to safely down-cast the argument.
75   virtual bool Equals(const ConfigSelector* other) const = 0;
76
77   static bool Equals(const ConfigSelector* cs1, const ConfigSelector* cs2) {
78     if (cs1 == nullptr) return cs2 == nullptr;
79     if (cs2 == nullptr) return false;
80     if (strcmp(cs1->name(), cs2->name()) != 0) return false;
81     return cs1->Equals(cs2);
82   }
83
84   virtual CallConfig GetCallConfig(GetCallConfigArgs args) = 0;
85
86   grpc_arg MakeChannelArg() const;
87   static RefCountedPtr<ConfigSelector> GetFromChannelArgs(
88       const grpc_channel_args& args);
89 };
90
91 // Default ConfigSelector that gets the MethodConfig from the service config.
92 class DefaultConfigSelector : public ConfigSelector {
93  public:
94   explicit DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config)
95       : service_config_(std::move(service_config)) {
96     // The client channel code ensures that this will never be null.
97     // If neither the resolver nor the client application provide a
98     // config, a default empty config will be used.
99     GPR_DEBUG_ASSERT(service_config_ != nullptr);
100   }
101
102   const char* name() const override { return "default"; }
103
104   // Only comparing the ConfigSelector itself, not the underlying
105   // service config, so we always return true.
106   bool Equals(const ConfigSelector* other) const override { return true; }
107
108   CallConfig GetCallConfig(GetCallConfigArgs args) override {
109     CallConfig call_config;
110     call_config.method_configs =
111         service_config_->GetMethodParsedConfigVector(*args.path);
112     call_config.service_config = service_config_;
113     return call_config;
114   }
115
116  private:
117   RefCountedPtr<ServiceConfig> service_config_;
118 };
119
120 }  // namespace grpc_core
121
122 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H */