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* 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 GetFilters()85 virtual std::vector<const grpc_channel_filter*> GetFilters() { return {}; } 86 87 virtual CallConfig GetCallConfig(GetCallConfigArgs args) = 0; 88 89 grpc_arg MakeChannelArg() const; 90 static RefCountedPtr<ConfigSelector> GetFromChannelArgs( 91 const grpc_channel_args& args); 92 }; 93 94 // Default ConfigSelector that gets the MethodConfig from the service config. 95 class DefaultConfigSelector : public ConfigSelector { 96 public: DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config)97 explicit DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config) 98 : service_config_(std::move(service_config)) { 99 // The client channel code ensures that this will never be null. 100 // If neither the resolver nor the client application provide a 101 // config, a default empty config will be used. 102 GPR_DEBUG_ASSERT(service_config_ != nullptr); 103 } 104 name()105 const char* name() const override { return "default"; } 106 107 // Only comparing the ConfigSelector itself, not the underlying 108 // service config, so we always return true. Equals(const ConfigSelector * other)109 bool Equals(const ConfigSelector* other) const override { return true; } 110 GetCallConfig(GetCallConfigArgs args)111 CallConfig GetCallConfig(GetCallConfigArgs args) override { 112 CallConfig call_config; 113 call_config.method_configs = 114 service_config_->GetMethodParsedConfigVector(*args.path); 115 call_config.service_config = service_config_; 116 return call_config; 117 } 118 119 private: 120 RefCountedPtr<ServiceConfig> service_config_; 121 }; 122 123 } // namespace grpc_core 124 125 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H */ 126