• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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