1 // Copyright 2021 gRPC authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GRPC_SRC_CORE_CONFIG_CORE_CONFIGURATION_H 16 #define GRPC_SRC_CORE_CONFIG_CORE_CONFIGURATION_H 17 18 #include <grpc/support/port_platform.h> 19 20 #include <atomic> 21 22 #include "absl/functional/any_invocable.h" 23 #include "absl/log/check.h" 24 #include "src/core/handshaker/handshaker_registry.h" 25 #include "src/core/handshaker/proxy_mapper_registry.h" 26 #include "src/core/lib/channel/channel_args_preconditioning.h" 27 #include "src/core/lib/security/certificate_provider/certificate_provider_registry.h" 28 #include "src/core/lib/security/credentials/channel_creds_registry.h" 29 #include "src/core/lib/surface/channel_init.h" 30 #include "src/core/load_balancing/lb_policy_registry.h" 31 #include "src/core/resolver/resolver_registry.h" 32 #include "src/core/service_config/service_config_parser.h" 33 34 namespace grpc_core { 35 36 // Global singleton that stores library configuration - factories, etc... 37 // that plugins might choose to extend. 38 class GRPC_DLL CoreConfiguration { 39 public: 40 CoreConfiguration(const CoreConfiguration&) = delete; 41 CoreConfiguration& operator=(const CoreConfiguration&) = delete; 42 43 // Builder is passed to plugins, etc... at initialization time to collect 44 // their configuration and assemble the published CoreConfiguration. 45 class Builder { 46 public: channel_args_preconditioning()47 ChannelArgsPreconditioning::Builder* channel_args_preconditioning() { 48 return &channel_args_preconditioning_; 49 } 50 channel_init()51 ChannelInit::Builder* channel_init() { return &channel_init_; } 52 handshaker_registry()53 HandshakerRegistry::Builder* handshaker_registry() { 54 return &handshaker_registry_; 55 } 56 channel_creds_registry()57 ChannelCredsRegistry<>::Builder* channel_creds_registry() { 58 return &channel_creds_registry_; 59 } 60 service_config_parser()61 ServiceConfigParser::Builder* service_config_parser() { 62 return &service_config_parser_; 63 } 64 resolver_registry()65 ResolverRegistry::Builder* resolver_registry() { 66 return &resolver_registry_; 67 } 68 lb_policy_registry()69 LoadBalancingPolicyRegistry::Builder* lb_policy_registry() { 70 return &lb_policy_registry_; 71 } 72 proxy_mapper_registry()73 ProxyMapperRegistry::Builder* proxy_mapper_registry() { 74 return &proxy_mapper_registry_; 75 } 76 certificate_provider_registry()77 CertificateProviderRegistry::Builder* certificate_provider_registry() { 78 return &certificate_provider_registry_; 79 } 80 81 private: 82 friend class CoreConfiguration; 83 84 ChannelArgsPreconditioning::Builder channel_args_preconditioning_; 85 ChannelInit::Builder channel_init_; 86 HandshakerRegistry::Builder handshaker_registry_; 87 ChannelCredsRegistry<>::Builder channel_creds_registry_; 88 ServiceConfigParser::Builder service_config_parser_; 89 ResolverRegistry::Builder resolver_registry_; 90 LoadBalancingPolicyRegistry::Builder lb_policy_registry_; 91 ProxyMapperRegistry::Builder proxy_mapper_registry_; 92 CertificateProviderRegistry::Builder certificate_provider_registry_; 93 94 Builder(); 95 CoreConfiguration* Build(); 96 }; 97 98 // Stores a builder for RegisterBuilder 99 struct RegisteredBuilder { 100 absl::AnyInvocable<void(Builder*)> builder; 101 RegisteredBuilder* next; 102 }; 103 104 // Temporarily replaces core configuration with what is built from the 105 // provided BuildFunc that takes (Builder*) and returns void. 106 // Requires no concurrent Get() be called. Restores current core 107 // configuration when this object is destroyed. The default builder 108 // is not backed up or restored. 109 // 110 // Useful for running multiple tests back to back in the same process 111 // without side effects from previous tests. 112 class WithSubstituteBuilder { 113 public: 114 template <typename BuildFunc> WithSubstituteBuilder(BuildFunc build)115 explicit WithSubstituteBuilder(BuildFunc build) { 116 // Build core configuration to replace. 117 Builder builder; 118 build(&builder); 119 CoreConfiguration* p = builder.Build(); 120 121 // Backup current core configuration and replace/reset. 122 config_restore_ = 123 CoreConfiguration::config_.exchange(p, std::memory_order_acquire); 124 builders_restore_ = CoreConfiguration::builders_.exchange( 125 nullptr, std::memory_order_acquire); 126 } 127 ~WithSubstituteBuilder()128 ~WithSubstituteBuilder() { 129 // Reset and restore. 130 Reset(); 131 CHECK(CoreConfiguration::config_.exchange( 132 config_restore_, std::memory_order_acquire) == nullptr); 133 CHECK(CoreConfiguration::builders_.exchange( 134 builders_restore_, std::memory_order_acquire) == nullptr); 135 } 136 137 private: 138 CoreConfiguration* config_restore_; 139 RegisteredBuilder* builders_restore_; 140 }; 141 142 // Lifetime methods 143 144 // Get the core configuration; if it does not exist, create it. Get()145 static const CoreConfiguration& Get() { 146 CoreConfiguration* p = config_.load(std::memory_order_acquire); 147 if (p != nullptr) { 148 return *p; 149 } 150 return BuildNewAndMaybeSet(); 151 } 152 153 // Attach a registration function globally. 154 // Each registration function is called *in addition to* 155 // BuildCoreConfiguration for the default core configuration. 156 static void RegisterBuilder(absl::AnyInvocable<void(Builder*)> builder); 157 158 // Drop the core configuration. Users must ensure no other threads are 159 // accessing the configuration. 160 // Clears any dynamically registered builders. 161 static void Reset(); 162 163 // Helper for tests: Reset the configuration, build a special one, run some 164 // code, and then reset the configuration again. 165 // Templatized to be sure no codegen in normal builds. 166 template <typename BuildFunc, typename RunFunc> RunWithSpecialConfiguration(BuildFunc build_configuration,RunFunc code_to_run)167 static void RunWithSpecialConfiguration(BuildFunc build_configuration, 168 RunFunc code_to_run) { 169 WithSubstituteBuilder builder(build_configuration); 170 code_to_run(); 171 } 172 173 // Accessors 174 channel_args_preconditioning()175 const ChannelArgsPreconditioning& channel_args_preconditioning() const { 176 return channel_args_preconditioning_; 177 } 178 channel_init()179 const ChannelInit& channel_init() const { return channel_init_; } 180 handshaker_registry()181 const HandshakerRegistry& handshaker_registry() const { 182 return handshaker_registry_; 183 } 184 channel_creds_registry()185 const ChannelCredsRegistry<>& channel_creds_registry() const { 186 return channel_creds_registry_; 187 } 188 service_config_parser()189 const ServiceConfigParser& service_config_parser() const { 190 return service_config_parser_; 191 } 192 resolver_registry()193 const ResolverRegistry& resolver_registry() const { 194 return resolver_registry_; 195 } 196 lb_policy_registry()197 const LoadBalancingPolicyRegistry& lb_policy_registry() const { 198 return lb_policy_registry_; 199 } 200 proxy_mapper_registry()201 const ProxyMapperRegistry& proxy_mapper_registry() const { 202 return proxy_mapper_registry_; 203 } 204 certificate_provider_registry()205 const CertificateProviderRegistry& certificate_provider_registry() const { 206 return certificate_provider_registry_; 207 } 208 SetDefaultBuilder(void (* builder)(CoreConfiguration::Builder *))209 static void SetDefaultBuilder(void (*builder)(CoreConfiguration::Builder*)) { 210 default_builder_ = builder; 211 } 212 213 private: 214 explicit CoreConfiguration(Builder* builder); 215 216 // Create a new CoreConfiguration, and either set it or throw it away. 217 // We allow multiple CoreConfiguration's to be created in parallel. 218 static const CoreConfiguration& BuildNewAndMaybeSet(); 219 220 // The configuration 221 static std::atomic<CoreConfiguration*> config_; 222 // Extra registered builders 223 static std::atomic<RegisteredBuilder*> builders_; 224 // Default builder 225 static void (*default_builder_)(CoreConfiguration::Builder*); 226 227 ChannelArgsPreconditioning channel_args_preconditioning_; 228 ChannelInit channel_init_; 229 HandshakerRegistry handshaker_registry_; 230 ChannelCredsRegistry<> channel_creds_registry_; 231 ServiceConfigParser service_config_parser_; 232 ResolverRegistry resolver_registry_; 233 LoadBalancingPolicyRegistry lb_policy_registry_; 234 ProxyMapperRegistry proxy_mapper_registry_; 235 CertificateProviderRegistry certificate_provider_registry_; 236 }; 237 238 extern void BuildCoreConfiguration(CoreConfiguration::Builder* builder); 239 240 } // namespace grpc_core 241 242 #endif // GRPC_SRC_CORE_CONFIG_CORE_CONFIGURATION_H 243