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