• 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_SRC_CORE_CLIENT_CHANNEL_CONFIG_SELECTOR_H
18 #define GRPC_SRC_CORE_CLIENT_CHANNEL_CONFIG_SELECTOR_H
19 
20 #include <grpc/grpc.h>
21 #include <grpc/support/port_platform.h>
22 #include <string.h>
23 
24 #include <utility>
25 #include <vector>
26 
27 #include "absl/log/check.h"
28 #include "absl/status/status.h"
29 #include "absl/strings/string_view.h"
30 #include "src/core/client_channel/client_channel_internal.h"
31 #include "src/core/lib/channel/channel_fwd.h"
32 #include "src/core/lib/resource_quota/arena.h"
33 #include "src/core/lib/slice/slice.h"
34 #include "src/core/lib/transport/interception_chain.h"
35 #include "src/core/lib/transport/metadata_batch.h"
36 #include "src/core/service_config/service_config.h"
37 #include "src/core/util/ref_counted.h"
38 #include "src/core/util/ref_counted_ptr.h"
39 #include "src/core/util/unique_type_name.h"
40 #include "src/core/util/useful.h"
41 
42 // Channel arg key for ConfigSelector.
43 #define GRPC_ARG_CONFIG_SELECTOR "grpc.internal.config_selector"
44 
45 namespace grpc_core {
46 
47 // Internal API used to allow resolver implementations to override
48 // MethodConfig and provide input to LB policies on a per-call basis.
49 class ConfigSelector : public RefCounted<ConfigSelector> {
50  public:
51   ~ConfigSelector() override = default;
52 
53   virtual UniqueTypeName name() const = 0;
54 
Equals(const ConfigSelector * cs1,const ConfigSelector * cs2)55   static bool Equals(const ConfigSelector* cs1, const ConfigSelector* cs2) {
56     if (cs1 == nullptr) return cs2 == nullptr;
57     if (cs2 == nullptr) return false;
58     if (cs1->name() != cs2->name()) return false;
59     return cs1->Equals(cs2);
60   }
61 
62   // The channel will call this when the resolver returns a new ConfigSelector
63   // to determine what set of dynamic filters will be configured.
AddFilters(InterceptionChainBuilder &)64   virtual void AddFilters(InterceptionChainBuilder& /*builder*/) {}
65   // TODO(roth): Remove this once the legacy filter stack goes away.
GetFilters()66   virtual std::vector<const grpc_channel_filter*> GetFilters() { return {}; }
67 
68   // Gets the configuration for the call and stores it in service config
69   // call data.
70   struct GetCallConfigArgs {
71     grpc_metadata_batch* initial_metadata;
72     Arena* arena;
73     ClientChannelServiceConfigCallData* service_config_call_data;
74   };
75   virtual absl::Status GetCallConfig(GetCallConfigArgs args) = 0;
76 
ChannelArgName()77   static absl::string_view ChannelArgName() { return GRPC_ARG_CONFIG_SELECTOR; }
ChannelArgsCompare(const ConfigSelector * a,const ConfigSelector * b)78   static int ChannelArgsCompare(const ConfigSelector* a,
79                                 const ConfigSelector* b) {
80     return QsortCompare(a, b);
81   }
82 
83  private:
84   // Will be called only if the two objects have the same name, so
85   // subclasses can be free to safely down-cast the argument.
86   virtual bool Equals(const ConfigSelector* other) const = 0;
87 };
88 
89 // Default ConfigSelector that gets the MethodConfig from the service config.
90 class DefaultConfigSelector final : public ConfigSelector {
91  public:
DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config)92   explicit DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config)
93       : service_config_(std::move(service_config)) {
94     // The client channel code ensures that this will never be null.
95     // If neither the resolver nor the client application provide a
96     // config, a default empty config will be used.
97     DCHECK(service_config_ != nullptr);
98   }
99 
name()100   UniqueTypeName name() const override {
101     static UniqueTypeName::Factory kFactory("default");
102     return kFactory.Create();
103   }
104 
GetCallConfig(GetCallConfigArgs args)105   absl::Status GetCallConfig(GetCallConfigArgs args) override {
106     Slice* path = args.initial_metadata->get_pointer(HttpPathMetadata());
107     CHECK_NE(path, nullptr);
108     auto* parsed_method_configs =
109         service_config_->GetMethodParsedConfigVector(path->c_slice());
110     args.service_config_call_data->SetServiceConfig(service_config_,
111                                                     parsed_method_configs);
112     return absl::OkStatus();
113   }
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 
119  private:
120   RefCountedPtr<ServiceConfig> service_config_;
121 };
122 
123 }  // namespace grpc_core
124 
125 #endif  // GRPC_SRC_CORE_CLIENT_CHANNEL_CONFIG_SELECTOR_H
126