2 // Copyright 2016 gRPC authors.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H
18 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H
20 #include <grpc/support/port_platform.h>
22 #include <grpc/impl/codegen/grpc_types.h>
23 #include <grpc/support/string_util.h>
25 #include "src/core/lib/gprpp/inlined_vector.h"
26 #include "src/core/lib/gprpp/ref_counted.h"
27 #include "src/core/lib/gprpp/ref_counted_ptr.h"
28 #include "src/core/lib/iomgr/error.h"
29 #include "src/core/lib/json/json.h"
30 #include "src/core/lib/slice/slice_hash_table.h"
32 // The main purpose of the code here is to parse the service config in
33 // JSON form, which will look like this:
36 // "loadBalancingPolicy": "string", // optional
37 // "methodConfig": [ // array of one or more method_config objects
39 // "name": [ // array of one or more name objects
41 // "service": "string", // required
42 // "method": "string", // optional
45 // // remaining fields are optional.
46 // // see https://developers.google.com/protocol-buffers/docs/proto3#json
47 // // for format details.
48 // "waitForReady": bool,
49 // "timeout": "duration_string",
50 // "maxRequestMessageBytes": "int64_string",
51 // "maxResponseMessageBytes": "int64_string",
58 class ServiceConfig : public RefCounted<ServiceConfig> {
60 /// This is the base class that all service config parsers MUST use to store
61 /// parsed service config data.
64 virtual ~ParsedConfig() = default;
66 GRPC_ABSTRACT_BASE_CLASS;
69 /// This is the base class that all service config parsers should derive from.
72 virtual ~Parser() = default;
74 virtual UniquePtr<ParsedConfig> ParseGlobalParams(const grpc_json* json,
76 GPR_DEBUG_ASSERT(error != nullptr);
80 virtual UniquePtr<ParsedConfig> ParsePerMethodParams(const grpc_json* json,
82 GPR_DEBUG_ASSERT(error != nullptr);
86 GRPC_ABSTRACT_BASE_CLASS;
89 static constexpr int kNumPreallocatedParsers = 4;
90 typedef InlinedVector<UniquePtr<ParsedConfig>, kNumPreallocatedParsers>
91 ServiceConfigObjectsVector;
93 /// When a service config is applied to a call in the client_channel_filter,
94 /// we create an instance of this object and store it in the call_data for
95 /// client_channel. A pointer to this object is also stored in the
96 /// call_context, so that future filters can easily access method and global
97 /// parameters for the call.
100 CallData() = default;
101 CallData(RefCountedPtr<ServiceConfig> svc_cfg, const grpc_slice& path)
102 : service_config_(std::move(svc_cfg)) {
103 if (service_config_ != nullptr) {
104 method_params_vector_ =
105 service_config_->GetMethodServiceConfigObjectsVector(path);
109 ServiceConfig* service_config() { return service_config_.get(); }
111 ParsedConfig* GetMethodParsedObject(size_t index) const {
112 return method_params_vector_ != nullptr
113 ? (*method_params_vector_)[index].get()
117 ParsedConfig* GetGlobalParsedObject(size_t index) const {
118 return service_config_->GetParsedGlobalServiceConfigObject(index);
122 RefCountedPtr<ServiceConfig> service_config_;
123 const ServiceConfigObjectsVector* method_params_vector_ = nullptr;
126 /// Creates a new service config from parsing \a json_string.
127 /// Returns null on parse error.
128 static RefCountedPtr<ServiceConfig> Create(const char* json,
133 const char* service_config_json() const { return service_config_json_.get(); }
135 /// Retrieves the parsed global service config object at index \a index. The
136 /// lifetime of the returned object is tied to the lifetime of the
137 /// ServiceConfig object.
138 ParsedConfig* GetParsedGlobalServiceConfigObject(size_t index) {
139 GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size());
140 return parsed_global_service_config_objects_[index].get();
143 /// Retrieves the vector of method service config objects for a given path \a
144 /// path. The lifetime of the returned vector and contained objects is tied to
145 /// the lifetime of the ServiceConfig object.
146 const ServiceConfigObjectsVector* GetMethodServiceConfigObjectsVector(
147 const grpc_slice& path);
149 /// Globally register a service config parser. On successful registration, it
150 /// returns the index at which the parser was registered. On failure, -1 is
151 /// returned. Each new service config update will go through all the
152 /// registered parser. Each parser is responsible for reading the service
153 /// config json and returning a parsed object. This parsed object can later be
154 /// retrieved using the same index that was returned at registration time.
155 static size_t RegisterParser(UniquePtr<Parser> parser);
159 static void Shutdown();
162 // So New() can call our private ctor.
163 template <typename T, typename... Args>
164 friend T* New(Args&&... args);
166 // Takes ownership of \a json_tree.
167 ServiceConfig(UniquePtr<char> service_config_json,
168 UniquePtr<char> json_string, grpc_json* json_tree,
171 // Helper functions to parse the service config
172 grpc_error* ParseGlobalParams(const grpc_json* json_tree);
173 grpc_error* ParsePerMethodParams(const grpc_json* json_tree);
175 // Returns the number of names specified in the method config \a json.
176 static int CountNamesInMethodConfig(grpc_json* json);
178 // Returns a path string for the JSON name object specified by \a json.
179 // Returns null on error, and stores error in \a error.
180 static UniquePtr<char> ParseJsonMethodName(grpc_json* json,
183 grpc_error* ParseJsonMethodConfigToServiceConfigObjectsTable(
184 const grpc_json* json,
185 SliceHashTable<const ServiceConfigObjectsVector*>::Entry* entries,
188 UniquePtr<char> service_config_json_;
189 UniquePtr<char> json_string_; // Underlying storage for json_tree.
190 grpc_json* json_tree_;
192 InlinedVector<UniquePtr<ParsedConfig>, kNumPreallocatedParsers>
193 parsed_global_service_config_objects_;
194 // A map from the method name to the service config objects vector. Note that
195 // we are using a raw pointer and not a unique pointer so that we can use the
196 // same vector for multiple names.
197 RefCountedPtr<SliceHashTable<const ServiceConfigObjectsVector*>>
198 parsed_method_service_config_objects_table_;
199 // Storage for all the vectors that are being used in
200 // parsed_method_service_config_objects_table_.
201 InlinedVector<UniquePtr<ServiceConfigObjectsVector>, 32>
202 service_config_objects_vectors_storage_;
205 } // namespace grpc_core
207 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H */