service_config_impl.cc
Go to the documentation of this file.
1 //
2 // Copyright 2022 gRPC authors.
3 //
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
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16 
18 
20 
21 #include <string.h>
22 
23 #include <map>
24 #include <string>
25 #include <utility>
26 
27 #include "absl/memory/memory.h"
28 #include "absl/strings/str_cat.h"
29 
30 #include <grpc/support/log.h>
31 
34 #include "src/core/lib/json/json.h"
38 
39 namespace grpc_core {
40 
42  const grpc_channel_args* args, absl::string_view json_string,
44  GPR_DEBUG_ASSERT(error != nullptr);
46  if (!GRPC_ERROR_IS_NONE(*error)) return nullptr;
47  return MakeRefCounted<ServiceConfigImpl>(args, std::string(json_string),
48  std::move(json), error);
49 }
50 
52  std::string json_string, Json json,
54  : json_string_(std::move(json_string)), json_(std::move(json)) {
55  GPR_DEBUG_ASSERT(error != nullptr);
56  if (json_.type() != Json::Type::OBJECT) {
57  *error =
58  GRPC_ERROR_CREATE_FROM_STATIC_STRING("JSON value is not an object");
59  return;
60  }
61  std::vector<grpc_error_handle> error_list;
62  grpc_error_handle global_error = GRPC_ERROR_NONE;
65  args, json_, &global_error);
66  if (!GRPC_ERROR_IS_NONE(global_error)) error_list.push_back(global_error);
68  if (!GRPC_ERROR_IS_NONE(local_error)) error_list.push_back(local_error);
69  if (!error_list.empty()) {
70  *error = GRPC_ERROR_CREATE_FROM_VECTOR("Service config parsing error",
71  &error_list);
72  }
73 }
74 
76  for (auto& p : parsed_method_configs_map_) {
78  }
79 }
80 
82  const grpc_channel_args* args, const Json& json) {
83  std::vector<grpc_error_handle> error_list;
84  // Parse method config with each registered parser.
85  auto parsed_configs =
86  absl::make_unique<ServiceConfigParser::ParsedConfigVector>();
87  grpc_error_handle parser_error = GRPC_ERROR_NONE;
88  *parsed_configs =
90  args, json, &parser_error);
91  if (!GRPC_ERROR_IS_NONE(parser_error)) {
92  error_list.push_back(parser_error);
93  }
94  parsed_method_config_vectors_storage_.push_back(std::move(parsed_configs));
95  const auto* vector_ptr = parsed_method_config_vectors_storage_.back().get();
96  // Add an entry for each path.
97  bool found_name = false;
98  auto it = json.object_value().find("name");
99  if (it != json.object_value().end()) {
100  if (it->second.type() != Json::Type::ARRAY) {
101  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
102  "field:name error:not of type Array"));
103  return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list);
104  }
105  const Json::Array& name_array = it->second.array_value();
106  for (const Json& name : name_array) {
110  error_list.push_back(parse_error);
111  } else {
112  found_name = true;
113  if (path.empty()) {
114  if (default_method_config_vector_ != nullptr) {
115  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
116  "field:name error:multiple default method configs"));
117  }
118  default_method_config_vector_ = vector_ptr;
119  } else {
121  // If the key is not already present in the map, this will
122  // store a ref to the key in the map.
124  if (value != nullptr) {
125  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
126  "field:name error:multiple method configs with same name"));
127  // The map entry already existed, so we need to unref the
128  // key we just created.
130  } else {
131  value = vector_ptr;
132  }
133  }
134  }
135  }
136  }
137  if (!found_name) {
139  }
140  return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list);
141 }
142 
144  const grpc_channel_args* args) {
145  std::vector<grpc_error_handle> error_list;
146  auto it = json_.object_value().find("methodConfig");
147  if (it != json_.object_value().end()) {
148  if (it->second.type() != Json::Type::ARRAY) {
149  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
150  "field:methodConfig error:not of type Array"));
151  }
152  for (const Json& method_config : it->second.array_value()) {
153  if (method_config.type() != Json::Type::OBJECT) {
154  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
155  "field:methodConfig error:not of type Object"));
156  continue;
157  }
159  if (!GRPC_ERROR_IS_NONE(error)) {
160  error_list.push_back(error);
161  }
162  }
163  }
164  return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list);
165 }
166 
169  if (json.type() != Json::Type::OBJECT) {
171  "field:name error:type is not object");
172  return "";
173  }
174  // Find service name.
175  const std::string* service_name = nullptr;
176  auto it = json.object_value().find("service");
177  if (it != json.object_value().end() &&
178  it->second.type() != Json::Type::JSON_NULL) {
179  if (it->second.type() != Json::Type::STRING) {
181  "field:name error: field:service error:not of type string");
182  return "";
183  }
184  if (!it->second.string_value().empty()) {
185  service_name = &it->second.string_value();
186  }
187  }
188  const std::string* method_name = nullptr;
189  // Find method name.
190  it = json.object_value().find("method");
191  if (it != json.object_value().end() &&
192  it->second.type() != Json::Type::JSON_NULL) {
193  if (it->second.type() != Json::Type::STRING) {
195  "field:name error: field:method error:not of type string");
196  return "";
197  }
198  if (!it->second.string_value().empty()) {
199  method_name = &it->second.string_value();
200  }
201  }
202  // If neither service nor method are specified, it's the default.
203  // Method name may not be specified without service name.
204  if (service_name == nullptr) {
205  if (method_name != nullptr) {
207  "field:name error:method name populated without service name");
208  }
209  return "";
210  }
211  // Construct path.
212  return absl::StrCat("/", *service_name, "/",
213  method_name == nullptr ? "" : *method_name);
214 }
215 
218  if (parsed_method_configs_map_.empty()) {
220  }
221  // Try looking up the full path in the map.
222  auto it = parsed_method_configs_map_.find(path);
223  if (it != parsed_method_configs_map_.end()) return it->second;
224  // If we didn't find a match for the path, try looking for a wildcard
225  // entry (i.e., change "/service/method" to "/service/").
227  char* sep = strrchr(path_str.get(), '/');
228  if (sep == nullptr) return nullptr; // Shouldn't ever happen.
229  sep[1] = '\0';
230  grpc_slice wildcard_path = grpc_slice_from_static_string(path_str.get());
231  it = parsed_method_configs_map_.find(wildcard_path);
232  if (it != parsed_method_configs_map_.end()) return it->second;
233  // Try default method config, if set.
235 }
236 
237 } // namespace grpc_core
grpc_core::Json::Array
std::vector< Json > Array
Definition: src/core/lib/json/json.h:55
grpc_core::ServiceConfigImpl::GetMethodParsedConfigVector
const ServiceConfigParser::ParsedConfigVector * GetMethodParsedConfigVector(const grpc_slice &path) const override
Definition: service_config_impl.cc:217
regen-readme.it
it
Definition: regen-readme.py:15
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
core_configuration.h
grpc_core::Json::type
Type type() const
Definition: src/core/lib/json/json.h:174
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
GPR_DEBUG_ASSERT
#define GPR_DEBUG_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:103
grpc_slice_from_copied_string
GPRAPI grpc_slice grpc_slice_from_copied_string(const char *source)
Definition: slice/slice.cc:177
grpc_core::Json::Type::OBJECT
@ OBJECT
grpc_core::CoreConfiguration::service_config_parser
const ServiceConfigParser & service_config_parser() const
Definition: core_configuration.h:153
grpc_core::ServiceConfigImpl::ParsePerMethodParams
grpc_error_handle ParsePerMethodParams(const grpc_channel_args *args)
Definition: service_config_impl.cc:143
grpc_core
Definition: call_metric_recorder.h:31
string.h
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
grpc_core::Json::object_value
const Object & object_value() const
Definition: src/core/lib/json/json.h:177
grpc_core::ServiceConfigParser::ParsedConfigVector
std::vector< std::unique_ptr< ParsedConfig > > ParsedConfigVector
Definition: lib/service_config/service_config_parser.h:77
setup.name
name
Definition: setup.py:542
check_documentation.path
path
Definition: check_documentation.py:57
grpc_channel_args
Definition: grpc_types.h:132
GRPC_ERROR_CREATE_FROM_VECTOR
#define GRPC_ERROR_CREATE_FROM_VECTOR(desc, error_list)
Definition: error.h:314
memory.h
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
grpc_core::RefCountedPtr
Definition: ref_counted_ptr.h:35
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
grpc_core::CoreConfiguration::Get
static const CoreConfiguration & Get()
Definition: core_configuration.h:82
grpc_core::ServiceConfigImpl::default_method_config_vector_
const ServiceConfigParser::ParsedConfigVector * default_method_config_vector_
Definition: service_config_impl.h:120
Json
JSON (JavaScript Object Notation).
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:227
text_format_test_wrapper.sep
sep
Definition: text_format_test_wrapper.py:34
grpc_core::ServiceConfigImpl::json_string
absl::string_view json_string() const override
Definition: service_config_impl.h:80
grpc_slice_from_static_string
GPRAPI grpc_slice grpc_slice_from_static_string(const char *source)
Definition: slice/slice.cc:89
grpc_core::ServiceConfigImpl::parsed_global_configs_
std::vector< std::unique_ptr< ServiceConfigParser::ParsedConfig > > parsed_global_configs_
Definition: service_config_impl.h:112
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
grpc_core::Json::Type::ARRAY
@ ARRAY
json.h
slice_internal.h
grpc_core::UniquePtr
std::unique_ptr< T, DefaultDeleteChar > UniquePtr
Definition: src/core/lib/gprpp/memory.h:43
grpc_core::ServiceConfigImpl::Create
static RefCountedPtr< ServiceConfig > Create(const grpc_channel_args *args, absl::string_view json_string, grpc_error_handle *error)
Definition: service_config_impl.cc:41
GRPC_ERROR_CREATE_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
Definition: error.h:291
service_config_parser.h
grpc_core::Json::Parse
static Json Parse(absl::string_view json_str, grpc_error_handle *error)
Definition: json_reader.cc:899
value
const char * value
Definition: hpack_parser_table.cc:165
grpc_slice_to_c_string
GPRAPI char * grpc_slice_to_c_string(grpc_slice s)
Definition: slice/slice.cc:35
key
const char * key
Definition: hpack_parser_table.cc:164
grpc_core::ServiceConfigImpl::parsed_method_config_vectors_storage_
std::vector< std::unique_ptr< ServiceConfigParser::ParsedConfigVector > > parsed_method_config_vectors_storage_
Definition: service_config_impl.h:125
grpc_core::ServiceConfigImpl::parsed_method_configs_map_
std::unordered_map< grpc_slice, const ServiceConfigParser::ParsedConfigVector *, SliceHash > parsed_method_configs_map_
Definition: service_config_impl.h:118
grpc_core::Json::Type::JSON_NULL
@ JSON_NULL
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
service_config_impl.h
slice_refcount.h
grpc_core::ServiceConfigImpl::~ServiceConfigImpl
~ServiceConfigImpl() override
Definition: service_config_impl.cc:75
grpc_core::ServiceConfigImpl::json_
Json json_
Definition: service_config_impl.h:109
method_config
RefCountedPtr< ServiceConfig > method_config
Definition: xds_resolver.cc:332
grpc_core::ServiceConfigParser::ParseGlobalParameters
ParsedConfigVector ParseGlobalParameters(const grpc_channel_args *args, const Json &json, grpc_error_handle *error) const
Definition: lib/service_config/service_config_parser.cc:51
grpc_core::ServiceConfigImpl::ParseJsonMethodName
static std::string ParseJsonMethodName(const Json &json, grpc_error_handle *error)
Definition: service_config_impl.cc:167
grpc_error
Definition: error_internal.h:42
method_name
absl::string_view method_name
Definition: call_creds_util.cc:40
grpc_core::ServiceConfigImpl::ServiceConfigImpl
ServiceConfigImpl(const grpc_channel_args *args, std::string json_string, Json json, grpc_error_handle *error)
Definition: service_config_impl.cc:51
grpc_core::ServiceConfigImpl::ParseJsonMethodConfig
grpc_error_handle ParseJsonMethodConfig(const grpc_channel_args *args, const Json &json)
Definition: service_config_impl.cc:81
grpc_core::Json::Type::STRING
@ STRING
grpc_core::ServiceConfigParser::ParsePerMethodParameters
ParsedConfigVector ParsePerMethodParameters(const grpc_channel_args *args, const Json &json, grpc_error_handle *error) const
Definition: lib/service_config/service_config_parser.cc:72
grpc_slice_unref_internal
void grpc_slice_unref_internal(const grpc_slice &slice)
Definition: slice_refcount.h:39
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
parse_error
@ parse_error
Definition: pem_info.c:88
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:17