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