• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2018 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 
17 #include "src/core/xds/xds_client/xds_api.h"
18 
19 #include "google/protobuf/struct.upb.h"
20 #include "src/core/util/json/json.h"
21 #include "src/core/util/upb_utils.h"
22 #include "upb/base/string_view.h"
23 #include "upb/mem/arena.hpp"
24 
25 namespace grpc_core {
26 
27 namespace {
28 
29 void PopulateMetadataValue(google_protobuf_Value* value_pb, const Json& value,
30                            upb_Arena* arena);
31 
PopulateListValue(google_protobuf_ListValue * list_value,const Json::Array & values,upb_Arena * arena)32 void PopulateListValue(google_protobuf_ListValue* list_value,
33                        const Json::Array& values, upb_Arena* arena) {
34   for (const auto& value : values) {
35     auto* value_pb = google_protobuf_ListValue_add_values(list_value, arena);
36     PopulateMetadataValue(value_pb, value, arena);
37   }
38 }
39 
PopulateMetadata(google_protobuf_Struct * metadata_pb,const Json::Object & metadata,upb_Arena * arena)40 void PopulateMetadata(google_protobuf_Struct* metadata_pb,
41                       const Json::Object& metadata, upb_Arena* arena) {
42   for (const auto& p : metadata) {
43     google_protobuf_Value* value = google_protobuf_Value_new(arena);
44     PopulateMetadataValue(value, p.second, arena);
45     google_protobuf_Struct_fields_set(
46         metadata_pb, StdStringToUpbString(p.first), value, arena);
47   }
48 }
49 
PopulateMetadataValue(google_protobuf_Value * value_pb,const Json & value,upb_Arena * arena)50 void PopulateMetadataValue(google_protobuf_Value* value_pb, const Json& value,
51                            upb_Arena* arena) {
52   switch (value.type()) {
53     case Json::Type::kNull:
54       google_protobuf_Value_set_null_value(value_pb, 0);
55       break;
56     case Json::Type::kNumber:
57       google_protobuf_Value_set_number_value(
58           value_pb, strtod(value.string().c_str(), nullptr));
59       break;
60     case Json::Type::kString:
61       google_protobuf_Value_set_string_value(
62           value_pb, StdStringToUpbString(value.string()));
63       break;
64     case Json::Type::kBoolean:
65       google_protobuf_Value_set_bool_value(value_pb, value.boolean());
66       break;
67     case Json::Type::kObject: {
68       google_protobuf_Struct* struct_value =
69           google_protobuf_Value_mutable_struct_value(value_pb, arena);
70       PopulateMetadata(struct_value, value.object(), arena);
71       break;
72     }
73     case Json::Type::kArray: {
74       google_protobuf_ListValue* list_value =
75           google_protobuf_Value_mutable_list_value(value_pb, arena);
76       PopulateListValue(list_value, value.array(), arena);
77       break;
78     }
79   }
80 }
81 
82 }  // namespace
83 
PopulateXdsNode(const XdsBootstrap::Node * node,absl::string_view user_agent_name,absl::string_view user_agent_version,envoy_config_core_v3_Node * node_msg,upb_Arena * arena)84 void PopulateXdsNode(const XdsBootstrap::Node* node,
85                      absl::string_view user_agent_name,
86                      absl::string_view user_agent_version,
87                      envoy_config_core_v3_Node* node_msg, upb_Arena* arena) {
88   if (node != nullptr) {
89     if (!node->id().empty()) {
90       envoy_config_core_v3_Node_set_id(node_msg,
91                                        StdStringToUpbString(node->id()));
92     }
93     if (!node->cluster().empty()) {
94       envoy_config_core_v3_Node_set_cluster(
95           node_msg, StdStringToUpbString(node->cluster()));
96     }
97     if (!node->metadata().empty()) {
98       google_protobuf_Struct* metadata =
99           envoy_config_core_v3_Node_mutable_metadata(node_msg, arena);
100       PopulateMetadata(metadata, node->metadata(), arena);
101     }
102     if (!node->locality_region().empty() || !node->locality_zone().empty() ||
103         !node->locality_sub_zone().empty()) {
104       envoy_config_core_v3_Locality* locality =
105           envoy_config_core_v3_Node_mutable_locality(node_msg, arena);
106       if (!node->locality_region().empty()) {
107         envoy_config_core_v3_Locality_set_region(
108             locality, StdStringToUpbString(node->locality_region()));
109       }
110       if (!node->locality_zone().empty()) {
111         envoy_config_core_v3_Locality_set_zone(
112             locality, StdStringToUpbString(node->locality_zone()));
113       }
114       if (!node->locality_sub_zone().empty()) {
115         envoy_config_core_v3_Locality_set_sub_zone(
116             locality, StdStringToUpbString(node->locality_sub_zone()));
117       }
118     }
119   }
120   envoy_config_core_v3_Node_set_user_agent_name(
121       node_msg, StdStringToUpbString(user_agent_name));
122   envoy_config_core_v3_Node_set_user_agent_version(
123       node_msg, StdStringToUpbString(user_agent_version));
124   envoy_config_core_v3_Node_add_client_features(
125       node_msg,
126       upb_StringView_FromString("envoy.lb.does_not_support_overprovisioning"),
127       arena);
128 }
129 
130 }  // namespace grpc_core
131