grpc 1.28.0.pre2 → 1.28.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +8 -2
- data/src/core/ext/filters/client_channel/client_channel.cc +27 -3
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +291 -0
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +83 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +37 -178
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +38 -9
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +242 -396
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +27 -5
- data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +27 -165
- data/src/core/ext/filters/client_channel/resolving_lb_policy.h +2 -4
- data/src/core/ext/filters/client_channel/xds/xds_api.cc +679 -56
- data/src/core/ext/filters/client_channel/xds/xds_api.h +30 -9
- data/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc +82 -5
- data/src/core/ext/filters/client_channel/xds/xds_bootstrap.h +5 -1
- data/src/core/ext/filters/client_channel/xds/xds_client.cc +273 -137
- data/src/core/ext/filters/client_channel/xds/xds_client.h +28 -12
- data/src/core/lib/gprpp/sync.h +9 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +32 -30
@@ -24,6 +24,8 @@
|
|
24
24
|
|
25
25
|
namespace grpc_core {
|
26
26
|
|
27
|
+
TraceFlag grpc_xds_resolver_trace(false, "xds_resolver");
|
28
|
+
|
27
29
|
namespace {
|
28
30
|
|
29
31
|
//
|
@@ -38,14 +40,28 @@ class XdsResolver : public Resolver {
|
|
38
40
|
interested_parties_(args.pollset_set) {
|
39
41
|
char* path = args.uri->path;
|
40
42
|
if (path[0] == '/') ++path;
|
41
|
-
server_name_
|
43
|
+
server_name_ = path;
|
44
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
|
45
|
+
gpr_log(GPR_INFO, "[xds_resolver %p] created for server name %s", this,
|
46
|
+
server_name_.c_str());
|
47
|
+
}
|
42
48
|
}
|
43
49
|
|
44
|
-
~XdsResolver() override {
|
50
|
+
~XdsResolver() override {
|
51
|
+
grpc_channel_args_destroy(args_);
|
52
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
|
53
|
+
gpr_log(GPR_INFO, "[xds_resolver %p] destroyed", this);
|
54
|
+
}
|
55
|
+
}
|
45
56
|
|
46
57
|
void StartLocked() override;
|
47
58
|
|
48
|
-
void ShutdownLocked() override {
|
59
|
+
void ShutdownLocked() override {
|
60
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
|
61
|
+
gpr_log(GPR_INFO, "[xds_resolver %p] shutting down", this);
|
62
|
+
}
|
63
|
+
xds_client_.reset();
|
64
|
+
}
|
49
65
|
|
50
66
|
private:
|
51
67
|
class ServiceConfigWatcher : public XdsClient::ServiceConfigWatcherInterface {
|
@@ -60,7 +76,7 @@ class XdsResolver : public Resolver {
|
|
60
76
|
RefCountedPtr<XdsResolver> resolver_;
|
61
77
|
};
|
62
78
|
|
63
|
-
|
79
|
+
std::string server_name_;
|
64
80
|
const grpc_channel_args* args_;
|
65
81
|
grpc_pollset_set* interested_parties_;
|
66
82
|
OrphanablePtr<XdsClient> xds_client_;
|
@@ -69,6 +85,10 @@ class XdsResolver : public Resolver {
|
|
69
85
|
void XdsResolver::ServiceConfigWatcher::OnServiceConfigChanged(
|
70
86
|
RefCountedPtr<ServiceConfig> service_config) {
|
71
87
|
if (resolver_->xds_client_ == nullptr) return;
|
88
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
|
89
|
+
gpr_log(GPR_INFO, "[xds_resolver %p] received updated service config: %s",
|
90
|
+
resolver_.get(), service_config->json_string().c_str());
|
91
|
+
}
|
72
92
|
grpc_arg xds_client_arg = resolver_->xds_client_->MakeChannelArg();
|
73
93
|
Result result;
|
74
94
|
result.args =
|
@@ -79,6 +99,8 @@ void XdsResolver::ServiceConfigWatcher::OnServiceConfigChanged(
|
|
79
99
|
|
80
100
|
void XdsResolver::ServiceConfigWatcher::OnError(grpc_error* error) {
|
81
101
|
if (resolver_->xds_client_ == nullptr) return;
|
102
|
+
gpr_log(GPR_ERROR, "[xds_resolver %p] received error: %s", resolver_.get(),
|
103
|
+
grpc_error_string(error));
|
82
104
|
grpc_arg xds_client_arg = resolver_->xds_client_->MakeChannelArg();
|
83
105
|
Result result;
|
84
106
|
result.args =
|
@@ -90,7 +112,7 @@ void XdsResolver::ServiceConfigWatcher::OnError(grpc_error* error) {
|
|
90
112
|
void XdsResolver::StartLocked() {
|
91
113
|
grpc_error* error = GRPC_ERROR_NONE;
|
92
114
|
xds_client_ = MakeOrphanable<XdsClient>(
|
93
|
-
combiner(), interested_parties_,
|
115
|
+
combiner(), interested_parties_, server_name_,
|
94
116
|
absl::make_unique<ServiceConfigWatcher>(Ref()), *args_, &error);
|
95
117
|
if (error != GRPC_ERROR_NONE) {
|
96
118
|
gpr_log(GPR_ERROR,
|
@@ -33,6 +33,7 @@
|
|
33
33
|
|
34
34
|
#include "src/core/ext/filters/client_channel/backup_poller.h"
|
35
35
|
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
|
36
|
+
#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
|
36
37
|
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
|
37
38
|
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
|
38
39
|
#include "src/core/ext/filters/client_channel/resolver_registry.h"
|
@@ -109,67 +110,31 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
|
|
109
110
|
RefCountedPtr<SubchannelInterface> CreateSubchannel(
|
110
111
|
const grpc_channel_args& args) override {
|
111
112
|
if (parent_->resolver_ == nullptr) return nullptr; // Shutting down.
|
112
|
-
if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr;
|
113
113
|
return parent_->channel_control_helper()->CreateSubchannel(args);
|
114
114
|
}
|
115
115
|
|
116
116
|
void UpdateState(grpc_connectivity_state state,
|
117
117
|
std::unique_ptr<SubchannelPicker> picker) override {
|
118
118
|
if (parent_->resolver_ == nullptr) return; // Shutting down.
|
119
|
-
// If this request is from the pending child policy, ignore it until
|
120
|
-
// it reports READY, at which point we swap it into place.
|
121
|
-
if (CalledByPendingChild()) {
|
122
|
-
if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) {
|
123
|
-
gpr_log(GPR_INFO,
|
124
|
-
"resolving_lb=%p helper=%p: pending child policy %p reports "
|
125
|
-
"state=%s",
|
126
|
-
parent_.get(), this, child_, ConnectivityStateName(state));
|
127
|
-
}
|
128
|
-
if (state != GRPC_CHANNEL_READY) return;
|
129
|
-
grpc_pollset_set_del_pollset_set(
|
130
|
-
parent_->lb_policy_->interested_parties(),
|
131
|
-
parent_->interested_parties());
|
132
|
-
parent_->lb_policy_ = std::move(parent_->pending_lb_policy_);
|
133
|
-
} else if (!CalledByCurrentChild()) {
|
134
|
-
// This request is from an outdated child, so ignore it.
|
135
|
-
return;
|
136
|
-
}
|
137
119
|
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
|
138
120
|
}
|
139
121
|
|
140
122
|
void RequestReresolution() override {
|
141
|
-
|
142
|
-
// from the current child policy (or any outdated child).
|
143
|
-
if (parent_->pending_lb_policy_ != nullptr && !CalledByPendingChild()) {
|
144
|
-
return;
|
145
|
-
}
|
123
|
+
if (parent_->resolver_ == nullptr) return; // Shutting down.
|
146
124
|
if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) {
|
147
125
|
gpr_log(GPR_INFO, "resolving_lb=%p: started name re-resolving",
|
148
126
|
parent_.get());
|
149
127
|
}
|
150
|
-
|
151
|
-
parent_->resolver_->RequestReresolutionLocked();
|
152
|
-
}
|
128
|
+
parent_->resolver_->RequestReresolutionLocked();
|
153
129
|
}
|
154
130
|
|
155
|
-
void AddTraceEvent(TraceSeverity
|
156
|
-
|
157
|
-
|
158
|
-
void set_child(LoadBalancingPolicy* child) { child_ = child; }
|
159
|
-
|
160
|
-
private:
|
161
|
-
bool CalledByPendingChild() const {
|
162
|
-
GPR_ASSERT(child_ != nullptr);
|
163
|
-
return child_ == parent_->pending_lb_policy_.get();
|
131
|
+
void AddTraceEvent(TraceSeverity severity, StringView message) override {
|
132
|
+
if (parent_->resolver_ == nullptr) return; // Shutting down.
|
133
|
+
parent_->channel_control_helper()->AddTraceEvent(severity, message);
|
164
134
|
}
|
165
135
|
|
166
|
-
|
167
|
-
GPR_ASSERT(child_ != nullptr);
|
168
|
-
return child_ == parent_->lb_policy_.get();
|
169
|
-
};
|
170
|
-
|
136
|
+
private:
|
171
137
|
RefCountedPtr<ResolvingLoadBalancingPolicy> parent_;
|
172
|
-
LoadBalancingPolicy* child_ = nullptr;
|
173
138
|
};
|
174
139
|
|
175
140
|
//
|
@@ -217,23 +182,11 @@ void ResolvingLoadBalancingPolicy::ShutdownLocked() {
|
|
217
182
|
interested_parties());
|
218
183
|
lb_policy_.reset();
|
219
184
|
}
|
220
|
-
if (pending_lb_policy_ != nullptr) {
|
221
|
-
if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
|
222
|
-
gpr_log(GPR_INFO, "resolving_lb=%p: shutting down pending lb_policy=%p",
|
223
|
-
this, pending_lb_policy_.get());
|
224
|
-
}
|
225
|
-
grpc_pollset_set_del_pollset_set(pending_lb_policy_->interested_parties(),
|
226
|
-
interested_parties());
|
227
|
-
pending_lb_policy_.reset();
|
228
|
-
}
|
229
185
|
}
|
230
186
|
}
|
231
187
|
|
232
188
|
void ResolvingLoadBalancingPolicy::ExitIdleLocked() {
|
233
|
-
if (lb_policy_ != nullptr)
|
234
|
-
lb_policy_->ExitIdleLocked();
|
235
|
-
if (pending_lb_policy_ != nullptr) pending_lb_policy_->ExitIdleLocked();
|
236
|
-
}
|
189
|
+
if (lb_policy_ != nullptr) lb_policy_->ExitIdleLocked();
|
237
190
|
}
|
238
191
|
|
239
192
|
void ResolvingLoadBalancingPolicy::ResetBackoffLocked() {
|
@@ -242,7 +195,6 @@ void ResolvingLoadBalancingPolicy::ResetBackoffLocked() {
|
|
242
195
|
resolver_->RequestReresolutionLocked();
|
243
196
|
}
|
244
197
|
if (lb_policy_ != nullptr) lb_policy_->ResetBackoffLocked();
|
245
|
-
if (pending_lb_policy_ != nullptr) pending_lb_policy_->ResetBackoffLocked();
|
246
198
|
}
|
247
199
|
|
248
200
|
void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) {
|
@@ -269,132 +221,42 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) {
|
|
269
221
|
|
270
222
|
void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked(
|
271
223
|
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
|
272
|
-
Resolver::Result result
|
273
|
-
//
|
274
|
-
// policy. When this happens, we leave child_policy_ as-is and store
|
275
|
-
// the new child policy in pending_child_policy_. Once the new child
|
276
|
-
// policy transitions into state READY, we swap it into child_policy_,
|
277
|
-
// replacing the original child policy. So pending_child_policy_ is
|
278
|
-
// non-null only between when we apply an update that changes the child
|
279
|
-
// policy name and when the new child reports state READY.
|
280
|
-
//
|
281
|
-
// Updates can arrive at any point during this transition. We always
|
282
|
-
// apply updates relative to the most recently created child policy,
|
283
|
-
// even if the most recent one is still in pending_child_policy_. This
|
284
|
-
// is true both when applying the updates to an existing child policy
|
285
|
-
// and when determining whether we need to create a new policy.
|
286
|
-
//
|
287
|
-
// As a result of this, there are several cases to consider here:
|
288
|
-
//
|
289
|
-
// 1. We have no existing child policy (i.e., we have started up but
|
290
|
-
// have not yet received a serverlist from the balancer or gone
|
291
|
-
// into fallback mode; in this case, both child_policy_ and
|
292
|
-
// pending_child_policy_ are null). In this case, we create a
|
293
|
-
// new child policy and store it in child_policy_.
|
294
|
-
//
|
295
|
-
// 2. We have an existing child policy and have no pending child policy
|
296
|
-
// from a previous update (i.e., either there has not been a
|
297
|
-
// previous update that changed the policy name, or we have already
|
298
|
-
// finished swapping in the new policy; in this case, child_policy_
|
299
|
-
// is non-null but pending_child_policy_ is null). In this case:
|
300
|
-
// a. If child_policy_->name() equals child_policy_name, then we
|
301
|
-
// update the existing child policy.
|
302
|
-
// b. If child_policy_->name() does not equal child_policy_name,
|
303
|
-
// we create a new policy. The policy will be stored in
|
304
|
-
// pending_child_policy_ and will later be swapped into
|
305
|
-
// child_policy_ by the helper when the new child transitions
|
306
|
-
// into state READY.
|
307
|
-
//
|
308
|
-
// 3. We have an existing child policy and have a pending child policy
|
309
|
-
// from a previous update (i.e., a previous update set
|
310
|
-
// pending_child_policy_ as per case 2b above and that policy has
|
311
|
-
// not yet transitioned into state READY and been swapped into
|
312
|
-
// child_policy_; in this case, both child_policy_ and
|
313
|
-
// pending_child_policy_ are non-null). In this case:
|
314
|
-
// a. If pending_child_policy_->name() equals child_policy_name,
|
315
|
-
// then we update the existing pending child policy.
|
316
|
-
// b. If pending_child_policy->name() does not equal
|
317
|
-
// child_policy_name, then we create a new policy. The new
|
318
|
-
// policy is stored in pending_child_policy_ (replacing the one
|
319
|
-
// that was there before, which will be immediately shut down)
|
320
|
-
// and will later be swapped into child_policy_ by the helper
|
321
|
-
// when the new child transitions into state READY.
|
322
|
-
const char* lb_policy_name = lb_policy_config->name();
|
323
|
-
const bool create_policy =
|
324
|
-
// case 1
|
325
|
-
lb_policy_ == nullptr ||
|
326
|
-
// case 2b
|
327
|
-
(pending_lb_policy_ == nullptr &&
|
328
|
-
strcmp(lb_policy_->name(), lb_policy_name) != 0) ||
|
329
|
-
// case 3b
|
330
|
-
(pending_lb_policy_ != nullptr &&
|
331
|
-
strcmp(pending_lb_policy_->name(), lb_policy_name) != 0);
|
332
|
-
LoadBalancingPolicy* policy_to_update = nullptr;
|
333
|
-
if (create_policy) {
|
334
|
-
// Cases 1, 2b, and 3b: create a new child policy.
|
335
|
-
// If lb_policy_ is null, we set it (case 1), else we set
|
336
|
-
// pending_lb_policy_ (cases 2b and 3b).
|
337
|
-
if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
|
338
|
-
gpr_log(GPR_INFO, "resolving_lb=%p: Creating new %schild policy %s", this,
|
339
|
-
lb_policy_ == nullptr ? "" : "pending ", lb_policy_name);
|
340
|
-
}
|
341
|
-
auto& lb_policy = lb_policy_ == nullptr ? lb_policy_ : pending_lb_policy_;
|
342
|
-
lb_policy =
|
343
|
-
CreateLbPolicyLocked(lb_policy_name, *result.args, trace_strings);
|
344
|
-
policy_to_update = lb_policy.get();
|
345
|
-
} else {
|
346
|
-
// Cases 2a and 3a: update an existing policy.
|
347
|
-
// If we have a pending child policy, send the update to the pending
|
348
|
-
// policy (case 3a), else send it to the current policy (case 2a).
|
349
|
-
policy_to_update = pending_lb_policy_ != nullptr ? pending_lb_policy_.get()
|
350
|
-
: lb_policy_.get();
|
351
|
-
}
|
352
|
-
GPR_ASSERT(policy_to_update != nullptr);
|
353
|
-
// Update the policy.
|
354
|
-
if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
|
355
|
-
gpr_log(GPR_INFO, "resolving_lb=%p: Updating %schild policy %p", this,
|
356
|
-
policy_to_update == pending_lb_policy_.get() ? "pending " : "",
|
357
|
-
policy_to_update);
|
358
|
-
}
|
224
|
+
Resolver::Result result) {
|
225
|
+
// Construct update.
|
359
226
|
UpdateArgs update_args;
|
360
227
|
update_args.addresses = std::move(result.addresses);
|
361
228
|
update_args.config = std::move(lb_policy_config);
|
362
229
|
// TODO(roth): Once channel args is converted to C++, use std::move() here.
|
363
230
|
update_args.args = result.args;
|
364
231
|
result.args = nullptr;
|
365
|
-
|
232
|
+
// Create policy if needed.
|
233
|
+
if (lb_policy_ == nullptr) {
|
234
|
+
lb_policy_ = CreateLbPolicyLocked(*update_args.args);
|
235
|
+
}
|
236
|
+
// Update the policy.
|
237
|
+
if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
|
238
|
+
gpr_log(GPR_INFO, "resolving_lb=%p: Updating child policy %p", this,
|
239
|
+
lb_policy_.get());
|
240
|
+
}
|
241
|
+
lb_policy_->UpdateLocked(std::move(update_args));
|
366
242
|
}
|
367
243
|
|
368
244
|
// Creates a new LB policy.
|
369
245
|
// Updates trace_strings to indicate what was done.
|
370
246
|
OrphanablePtr<LoadBalancingPolicy>
|
371
247
|
ResolvingLoadBalancingPolicy::CreateLbPolicyLocked(
|
372
|
-
const
|
373
|
-
TraceStringVector* trace_strings) {
|
374
|
-
ResolvingControlHelper* helper = new ResolvingControlHelper(Ref());
|
248
|
+
const grpc_channel_args& args) {
|
375
249
|
LoadBalancingPolicy::Args lb_policy_args;
|
376
250
|
lb_policy_args.combiner = combiner();
|
377
251
|
lb_policy_args.channel_control_helper =
|
378
|
-
|
252
|
+
absl::make_unique<ResolvingControlHelper>(Ref());
|
379
253
|
lb_policy_args.args = &args;
|
380
254
|
OrphanablePtr<LoadBalancingPolicy> lb_policy =
|
381
|
-
|
382
|
-
lb_policy_name, std::move(lb_policy_args));
|
383
|
-
if (GPR_UNLIKELY(lb_policy == nullptr)) {
|
384
|
-
gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name);
|
385
|
-
char* str;
|
386
|
-
gpr_asprintf(&str, "Could not create LB policy \"%s\"", lb_policy_name);
|
387
|
-
trace_strings->push_back(str);
|
388
|
-
return nullptr;
|
389
|
-
}
|
390
|
-
helper->set_child(lb_policy.get());
|
255
|
+
MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args), tracer_);
|
391
256
|
if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
|
392
|
-
gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy
|
393
|
-
|
257
|
+
gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy %p", this,
|
258
|
+
lb_policy.get());
|
394
259
|
}
|
395
|
-
char* str;
|
396
|
-
gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name);
|
397
|
-
trace_strings->push_back(str);
|
398
260
|
grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
|
399
261
|
interested_parties());
|
400
262
|
return lb_policy;
|
@@ -476,8 +338,8 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
|
|
476
338
|
}
|
477
339
|
if (lb_policy_config != nullptr) {
|
478
340
|
// Create or update LB policy, as needed.
|
479
|
-
CreateOrUpdateLbPolicyLocked(std::move(lb_policy_config),
|
480
|
-
|
341
|
+
CreateOrUpdateLbPolicyLocked(std::move(lb_policy_config),
|
342
|
+
std::move(result));
|
481
343
|
}
|
482
344
|
// Add channel trace event.
|
483
345
|
if (service_config_changed) {
|
@@ -92,10 +92,9 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
|
|
92
92
|
void OnResolverError(grpc_error* error);
|
93
93
|
void CreateOrUpdateLbPolicyLocked(
|
94
94
|
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
|
95
|
-
Resolver::Result result
|
95
|
+
Resolver::Result result);
|
96
96
|
OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
|
97
|
-
const
|
98
|
-
TraceStringVector* trace_strings);
|
97
|
+
const grpc_channel_args& args);
|
99
98
|
void MaybeAddTraceMessagesForAddressChangesLocked(
|
100
99
|
bool resolution_contains_addresses, TraceStringVector* trace_strings);
|
101
100
|
void ConcatenateAndAddChannelTraceLocked(
|
@@ -116,7 +115,6 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
|
|
116
115
|
|
117
116
|
// Child LB policy.
|
118
117
|
OrphanablePtr<LoadBalancingPolicy> lb_policy_;
|
119
|
-
OrphanablePtr<LoadBalancingPolicy> pending_lb_policy_;
|
120
118
|
};
|
121
119
|
|
122
120
|
} // namespace grpc_core
|
@@ -23,6 +23,7 @@
|
|
23
23
|
#include <cstdlib>
|
24
24
|
|
25
25
|
#include "absl/strings/str_cat.h"
|
26
|
+
#include "absl/strings/str_join.h"
|
26
27
|
|
27
28
|
#include <grpc/impl/codegen/log.h>
|
28
29
|
#include <grpc/support/alloc.h>
|
@@ -125,8 +126,11 @@ const char* XdsApi::kCdsTypeUrl = "type.googleapis.com/envoy.api.v2.Cluster";
|
|
125
126
|
const char* XdsApi::kEdsTypeUrl =
|
126
127
|
"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment";
|
127
128
|
|
128
|
-
XdsApi::XdsApi(
|
129
|
-
|
129
|
+
XdsApi::XdsApi(XdsClient* client, TraceFlag* tracer,
|
130
|
+
const XdsBootstrap::Node* node)
|
131
|
+
: client_(client),
|
132
|
+
tracer_(tracer),
|
133
|
+
node_(node),
|
130
134
|
build_version_(absl::StrCat("gRPC C-core ", GPR_PLATFORM_STRING, " ",
|
131
135
|
grpc_version_string())),
|
132
136
|
user_agent_name_(absl::StrCat("gRPC C-core ", GPR_PLATFORM_STRING)) {}
|
@@ -289,6 +293,162 @@ envoy_api_v2_DiscoveryRequest* CreateDiscoveryRequest(
|
|
289
293
|
return request;
|
290
294
|
}
|
291
295
|
|
296
|
+
inline absl::string_view UpbStringToAbsl(const upb_strview& str) {
|
297
|
+
return absl::string_view(str.data, str.size);
|
298
|
+
}
|
299
|
+
|
300
|
+
inline void AddStringField(const char* name, const upb_strview& value,
|
301
|
+
std::vector<std::string>* fields,
|
302
|
+
bool add_if_empty = false) {
|
303
|
+
if (value.size > 0 || add_if_empty) {
|
304
|
+
fields->emplace_back(
|
305
|
+
absl::StrCat(name, ": \"", UpbStringToAbsl(value), "\""));
|
306
|
+
}
|
307
|
+
}
|
308
|
+
|
309
|
+
inline void AddLocalityField(int indent_level,
|
310
|
+
const envoy_api_v2_core_Locality* locality,
|
311
|
+
std::vector<std::string>* fields) {
|
312
|
+
std::string indent =
|
313
|
+
absl::StrJoin(std::vector<std::string>(indent_level, " "), "");
|
314
|
+
// region
|
315
|
+
std::string field = absl::StrCat(indent, "region");
|
316
|
+
AddStringField(field.c_str(), envoy_api_v2_core_Locality_region(locality),
|
317
|
+
fields);
|
318
|
+
// zone
|
319
|
+
field = absl::StrCat(indent, "zone");
|
320
|
+
AddStringField(field.c_str(), envoy_api_v2_core_Locality_zone(locality),
|
321
|
+
fields);
|
322
|
+
// sub_zone
|
323
|
+
field = absl::StrCat(indent, "sub_zone");
|
324
|
+
AddStringField(field.c_str(), envoy_api_v2_core_Locality_sub_zone(locality),
|
325
|
+
fields);
|
326
|
+
}
|
327
|
+
|
328
|
+
void AddNodeLogFields(const envoy_api_v2_core_Node* node,
|
329
|
+
std::vector<std::string>* fields) {
|
330
|
+
fields->emplace_back("node {");
|
331
|
+
// id
|
332
|
+
AddStringField(" id", envoy_api_v2_core_Node_id(node), fields);
|
333
|
+
// metadata
|
334
|
+
const google_protobuf_Struct* metadata =
|
335
|
+
envoy_api_v2_core_Node_metadata(node);
|
336
|
+
if (metadata != nullptr) {
|
337
|
+
fields->emplace_back(" metadata {");
|
338
|
+
size_t num_entries;
|
339
|
+
const google_protobuf_Struct_FieldsEntry* const* entries =
|
340
|
+
google_protobuf_Struct_fields(metadata, &num_entries);
|
341
|
+
for (size_t i = 0; i < num_entries; ++i) {
|
342
|
+
fields->emplace_back(" field {");
|
343
|
+
// key
|
344
|
+
AddStringField(" key",
|
345
|
+
google_protobuf_Struct_FieldsEntry_key(entries[i]),
|
346
|
+
fields);
|
347
|
+
// value
|
348
|
+
const google_protobuf_Value* value =
|
349
|
+
google_protobuf_Struct_FieldsEntry_value(entries[i]);
|
350
|
+
if (value != nullptr) {
|
351
|
+
std::string value_str;
|
352
|
+
if (google_protobuf_Value_has_string_value(value)) {
|
353
|
+
value_str = absl::StrCat(
|
354
|
+
"string_value: \"",
|
355
|
+
UpbStringToAbsl(google_protobuf_Value_string_value(value)), "\"");
|
356
|
+
} else if (google_protobuf_Value_has_null_value(value)) {
|
357
|
+
value_str = "null_value: NULL_VALUE";
|
358
|
+
} else if (google_protobuf_Value_has_number_value(value)) {
|
359
|
+
value_str = absl::StrCat("double_value: ",
|
360
|
+
google_protobuf_Value_number_value(value));
|
361
|
+
} else if (google_protobuf_Value_has_bool_value(value)) {
|
362
|
+
value_str = absl::StrCat("bool_value: ",
|
363
|
+
google_protobuf_Value_bool_value(value));
|
364
|
+
} else if (google_protobuf_Value_has_struct_value(value)) {
|
365
|
+
value_str = "struct_value: <not printed>";
|
366
|
+
} else if (google_protobuf_Value_has_list_value(value)) {
|
367
|
+
value_str = "list_value: <not printed>";
|
368
|
+
} else {
|
369
|
+
value_str = "<unknown>";
|
370
|
+
}
|
371
|
+
fields->emplace_back(absl::StrCat(" value { ", value_str, " }"));
|
372
|
+
}
|
373
|
+
fields->emplace_back(" }");
|
374
|
+
}
|
375
|
+
fields->emplace_back(" }");
|
376
|
+
}
|
377
|
+
// locality
|
378
|
+
const envoy_api_v2_core_Locality* locality =
|
379
|
+
envoy_api_v2_core_Node_locality(node);
|
380
|
+
if (locality != nullptr) {
|
381
|
+
fields->emplace_back(" locality {");
|
382
|
+
AddLocalityField(2, locality, fields);
|
383
|
+
fields->emplace_back(" }");
|
384
|
+
}
|
385
|
+
// build_version
|
386
|
+
AddStringField(" build_version", envoy_api_v2_core_Node_build_version(node),
|
387
|
+
fields);
|
388
|
+
// user_agent_name
|
389
|
+
AddStringField(" user_agent_name",
|
390
|
+
envoy_api_v2_core_Node_user_agent_name(node), fields);
|
391
|
+
// user_agent_version
|
392
|
+
AddStringField(" user_agent_version",
|
393
|
+
envoy_api_v2_core_Node_user_agent_version(node), fields);
|
394
|
+
// client_features
|
395
|
+
size_t num_client_features;
|
396
|
+
const upb_strview* client_features =
|
397
|
+
envoy_api_v2_core_Node_client_features(node, &num_client_features);
|
398
|
+
for (size_t i = 0; i < num_client_features; ++i) {
|
399
|
+
AddStringField(" client_features", client_features[i], fields);
|
400
|
+
}
|
401
|
+
fields->emplace_back("}");
|
402
|
+
}
|
403
|
+
|
404
|
+
void MaybeLogDiscoveryRequest(XdsClient* client, TraceFlag* tracer,
|
405
|
+
const envoy_api_v2_DiscoveryRequest* request) {
|
406
|
+
if (GRPC_TRACE_FLAG_ENABLED(*tracer) &&
|
407
|
+
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
|
408
|
+
// TODO(roth): When we can upgrade upb, use upb textformat code to dump
|
409
|
+
// the raw proto instead of doing this manually.
|
410
|
+
std::vector<std::string> fields;
|
411
|
+
// version_info
|
412
|
+
AddStringField("version_info",
|
413
|
+
envoy_api_v2_DiscoveryRequest_version_info(request),
|
414
|
+
&fields);
|
415
|
+
// node
|
416
|
+
const envoy_api_v2_core_Node* node =
|
417
|
+
envoy_api_v2_DiscoveryRequest_node(request);
|
418
|
+
if (node != nullptr) AddNodeLogFields(node, &fields);
|
419
|
+
// resource_names
|
420
|
+
size_t num_resource_names;
|
421
|
+
const upb_strview* resource_names =
|
422
|
+
envoy_api_v2_DiscoveryRequest_resource_names(request,
|
423
|
+
&num_resource_names);
|
424
|
+
for (size_t i = 0; i < num_resource_names; ++i) {
|
425
|
+
AddStringField("resource_names", resource_names[i], &fields);
|
426
|
+
}
|
427
|
+
// type_url
|
428
|
+
AddStringField("type_url", envoy_api_v2_DiscoveryRequest_type_url(request),
|
429
|
+
&fields);
|
430
|
+
// response_nonce
|
431
|
+
AddStringField("response_nonce",
|
432
|
+
envoy_api_v2_DiscoveryRequest_response_nonce(request),
|
433
|
+
&fields);
|
434
|
+
// error_detail
|
435
|
+
const struct google_rpc_Status* error_detail =
|
436
|
+
envoy_api_v2_DiscoveryRequest_error_detail(request);
|
437
|
+
if (error_detail != nullptr) {
|
438
|
+
fields.emplace_back("error_detail {");
|
439
|
+
// code
|
440
|
+
int32_t code = google_rpc_Status_code(error_detail);
|
441
|
+
if (code != 0) fields.emplace_back(absl::StrCat(" code: ", code));
|
442
|
+
// message
|
443
|
+
AddStringField(" message", google_rpc_Status_message(error_detail),
|
444
|
+
&fields);
|
445
|
+
fields.emplace_back("}");
|
446
|
+
}
|
447
|
+
gpr_log(GPR_DEBUG, "[xds_client %p] constructed ADS request: %s", client,
|
448
|
+
absl::StrJoin(fields, "\n").c_str());
|
449
|
+
}
|
450
|
+
}
|
451
|
+
|
292
452
|
grpc_slice SerializeDiscoveryRequest(upb_arena* arena,
|
293
453
|
envoy_api_v2_DiscoveryRequest* request) {
|
294
454
|
size_t output_length;
|
@@ -305,6 +465,7 @@ grpc_slice XdsApi::CreateUnsupportedTypeNackRequest(const std::string& type_url,
|
|
305
465
|
upb::Arena arena;
|
306
466
|
envoy_api_v2_DiscoveryRequest* request = CreateDiscoveryRequest(
|
307
467
|
arena.ptr(), type_url.c_str(), /*version=*/"", nonce, error);
|
468
|
+
MaybeLogDiscoveryRequest(client_, tracer_, request);
|
308
469
|
return SerializeDiscoveryRequest(arena.ptr(), request);
|
309
470
|
}
|
310
471
|
|
@@ -326,6 +487,7 @@ grpc_slice XdsApi::CreateLdsRequest(const std::string& server_name,
|
|
326
487
|
envoy_api_v2_DiscoveryRequest_add_resource_names(
|
327
488
|
request, upb_strview_make(server_name.data(), server_name.size()),
|
328
489
|
arena.ptr());
|
490
|
+
MaybeLogDiscoveryRequest(client_, tracer_, request);
|
329
491
|
return SerializeDiscoveryRequest(arena.ptr(), request);
|
330
492
|
}
|
331
493
|
|
@@ -348,6 +510,7 @@ grpc_slice XdsApi::CreateRdsRequest(const std::string& route_config_name,
|
|
348
510
|
request,
|
349
511
|
upb_strview_make(route_config_name.data(), route_config_name.size()),
|
350
512
|
arena.ptr());
|
513
|
+
MaybeLogDiscoveryRequest(client_, tracer_, request);
|
351
514
|
return SerializeDiscoveryRequest(arena.ptr(), request);
|
352
515
|
}
|
353
516
|
|
@@ -371,6 +534,7 @@ grpc_slice XdsApi::CreateCdsRequest(const std::set<StringView>& cluster_names,
|
|
371
534
|
request, upb_strview_make(cluster_name.data(), cluster_name.size()),
|
372
535
|
arena.ptr());
|
373
536
|
}
|
537
|
+
MaybeLogDiscoveryRequest(client_, tracer_, request);
|
374
538
|
return SerializeDiscoveryRequest(arena.ptr(), request);
|
375
539
|
}
|
376
540
|
|
@@ -394,11 +558,347 @@ grpc_slice XdsApi::CreateEdsRequest(
|
|
394
558
|
upb_strview_make(eds_service_name.data(), eds_service_name.size()),
|
395
559
|
arena.ptr());
|
396
560
|
}
|
561
|
+
MaybeLogDiscoveryRequest(client_, tracer_, request);
|
397
562
|
return SerializeDiscoveryRequest(arena.ptr(), request);
|
398
563
|
}
|
399
564
|
|
400
565
|
namespace {
|
401
566
|
|
567
|
+
void MaybeLogDiscoveryResponse(XdsClient* client, TraceFlag* tracer,
|
568
|
+
const envoy_api_v2_DiscoveryResponse* response) {
|
569
|
+
if (GRPC_TRACE_FLAG_ENABLED(*tracer) &&
|
570
|
+
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
|
571
|
+
// TODO(roth): When we can upgrade upb, use upb textformat code to dump
|
572
|
+
// the raw proto instead of doing this manually.
|
573
|
+
std::vector<std::string> fields;
|
574
|
+
// version_info
|
575
|
+
AddStringField("version_info",
|
576
|
+
envoy_api_v2_DiscoveryResponse_version_info(response),
|
577
|
+
&fields);
|
578
|
+
// resources
|
579
|
+
size_t num_resources;
|
580
|
+
envoy_api_v2_DiscoveryResponse_resources(response, &num_resources);
|
581
|
+
fields.emplace_back(
|
582
|
+
absl::StrCat("resources: <", num_resources, " element(s)>"));
|
583
|
+
// type_url
|
584
|
+
AddStringField("type_url",
|
585
|
+
envoy_api_v2_DiscoveryResponse_type_url(response), &fields);
|
586
|
+
// nonce
|
587
|
+
AddStringField("nonce", envoy_api_v2_DiscoveryResponse_nonce(response),
|
588
|
+
&fields);
|
589
|
+
gpr_log(GPR_DEBUG, "[xds_client %p] received response: %s", client,
|
590
|
+
absl::StrJoin(fields, "\n").c_str());
|
591
|
+
}
|
592
|
+
}
|
593
|
+
|
594
|
+
void MaybeLogRouteConfiguration(
|
595
|
+
XdsClient* client, TraceFlag* tracer,
|
596
|
+
const envoy_api_v2_RouteConfiguration* route_config) {
|
597
|
+
if (GRPC_TRACE_FLAG_ENABLED(*tracer) &&
|
598
|
+
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
|
599
|
+
// TODO(roth): When we can upgrade upb, use upb textformat code to dump
|
600
|
+
// the raw proto instead of doing this manually.
|
601
|
+
std::vector<std::string> fields;
|
602
|
+
// name
|
603
|
+
AddStringField("name", envoy_api_v2_RouteConfiguration_name(route_config),
|
604
|
+
&fields);
|
605
|
+
// virtual_hosts
|
606
|
+
size_t num_virtual_hosts;
|
607
|
+
const envoy_api_v2_route_VirtualHost* const* virtual_hosts =
|
608
|
+
envoy_api_v2_RouteConfiguration_virtual_hosts(route_config,
|
609
|
+
&num_virtual_hosts);
|
610
|
+
for (size_t i = 0; i < num_virtual_hosts; ++i) {
|
611
|
+
const auto* virtual_host = virtual_hosts[i];
|
612
|
+
fields.push_back("virtual_hosts {");
|
613
|
+
// name
|
614
|
+
AddStringField(
|
615
|
+
" name", envoy_api_v2_route_VirtualHost_name(virtual_host), &fields);
|
616
|
+
// domains
|
617
|
+
size_t num_domains;
|
618
|
+
const upb_strview* const domains =
|
619
|
+
envoy_api_v2_route_VirtualHost_domains(virtual_host, &num_domains);
|
620
|
+
for (size_t j = 0; j < num_domains; ++j) {
|
621
|
+
AddStringField(" domains", domains[j], &fields);
|
622
|
+
}
|
623
|
+
// routes
|
624
|
+
size_t num_routes;
|
625
|
+
const envoy_api_v2_route_Route* const* routes =
|
626
|
+
envoy_api_v2_route_VirtualHost_routes(virtual_host, &num_routes);
|
627
|
+
for (size_t j = 0; j < num_routes; ++j) {
|
628
|
+
const auto* route = routes[j];
|
629
|
+
fields.push_back(" route {");
|
630
|
+
// name
|
631
|
+
AddStringField(" name", envoy_api_v2_route_Route_name(route),
|
632
|
+
&fields);
|
633
|
+
// match
|
634
|
+
const envoy_api_v2_route_RouteMatch* match =
|
635
|
+
envoy_api_v2_route_Route_match(route);
|
636
|
+
if (match != nullptr) {
|
637
|
+
fields.emplace_back(" match {");
|
638
|
+
// path matching
|
639
|
+
if (envoy_api_v2_route_RouteMatch_has_prefix(match)) {
|
640
|
+
AddStringField(" prefix",
|
641
|
+
envoy_api_v2_route_RouteMatch_prefix(match), &fields,
|
642
|
+
/*add_if_empty=*/true);
|
643
|
+
} else if (envoy_api_v2_route_RouteMatch_has_path(match)) {
|
644
|
+
AddStringField(" path",
|
645
|
+
envoy_api_v2_route_RouteMatch_path(match), &fields,
|
646
|
+
/*add_if_empty=*/true);
|
647
|
+
} else if (envoy_api_v2_route_RouteMatch_has_regex(match)) {
|
648
|
+
AddStringField(" regex",
|
649
|
+
envoy_api_v2_route_RouteMatch_regex(match), &fields,
|
650
|
+
/*add_if_empty=*/true);
|
651
|
+
} else if (envoy_api_v2_route_RouteMatch_has_safe_regex(match)) {
|
652
|
+
fields.emplace_back(" safe_regex: <not printed>");
|
653
|
+
} else {
|
654
|
+
fields.emplace_back(" <unknown path matching type>");
|
655
|
+
}
|
656
|
+
// header matching
|
657
|
+
size_t num_headers;
|
658
|
+
envoy_api_v2_route_RouteMatch_headers(match, &num_headers);
|
659
|
+
if (num_headers > 0) {
|
660
|
+
fields.emplace_back(
|
661
|
+
absl::StrCat(" headers: <", num_headers, " element(s)>"));
|
662
|
+
}
|
663
|
+
fields.emplace_back(" }");
|
664
|
+
}
|
665
|
+
// action
|
666
|
+
if (envoy_api_v2_route_Route_has_route(route)) {
|
667
|
+
const envoy_api_v2_route_RouteAction* action =
|
668
|
+
envoy_api_v2_route_Route_route(route);
|
669
|
+
fields.emplace_back(" route {");
|
670
|
+
if (envoy_api_v2_route_RouteAction_has_cluster(action)) {
|
671
|
+
AddStringField(" cluster",
|
672
|
+
envoy_api_v2_route_RouteAction_cluster(action),
|
673
|
+
&fields);
|
674
|
+
} else if (envoy_api_v2_route_RouteAction_has_cluster_header(
|
675
|
+
action)) {
|
676
|
+
AddStringField(
|
677
|
+
" cluster_header",
|
678
|
+
envoy_api_v2_route_RouteAction_cluster_header(action), &fields);
|
679
|
+
} else if (envoy_api_v2_route_RouteAction_has_weighted_clusters(
|
680
|
+
action)) {
|
681
|
+
fields.emplace_back(" weighted_clusters: <not printed>");
|
682
|
+
}
|
683
|
+
fields.emplace_back(" }");
|
684
|
+
} else if (envoy_api_v2_route_Route_has_redirect(route)) {
|
685
|
+
fields.emplace_back(" redirect: <not printed>");
|
686
|
+
} else if (envoy_api_v2_route_Route_has_direct_response(route)) {
|
687
|
+
fields.emplace_back(" direct_response: <not printed>");
|
688
|
+
} else if (envoy_api_v2_route_Route_has_filter_action(route)) {
|
689
|
+
fields.emplace_back(" filter_action: <not printed>");
|
690
|
+
}
|
691
|
+
fields.push_back(" }");
|
692
|
+
}
|
693
|
+
fields.push_back("}");
|
694
|
+
}
|
695
|
+
gpr_log(GPR_DEBUG, "[xds_client %p] RouteConfiguration: %s", client,
|
696
|
+
absl::StrJoin(fields, "\n").c_str());
|
697
|
+
}
|
698
|
+
}
|
699
|
+
|
700
|
+
void MaybeLogCluster(XdsClient* client, TraceFlag* tracer,
|
701
|
+
const envoy_api_v2_Cluster* cluster) {
|
702
|
+
if (GRPC_TRACE_FLAG_ENABLED(*tracer) &&
|
703
|
+
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
|
704
|
+
// TODO(roth): When we can upgrade upb, use upb textformat code to dump
|
705
|
+
// the raw proto instead of doing this manually.
|
706
|
+
std::vector<std::string> fields;
|
707
|
+
// name
|
708
|
+
AddStringField("name", envoy_api_v2_Cluster_name(cluster), &fields);
|
709
|
+
// type
|
710
|
+
if (envoy_api_v2_Cluster_has_type(cluster)) {
|
711
|
+
fields.emplace_back(
|
712
|
+
absl::StrCat("type: ", envoy_api_v2_Cluster_type(cluster)));
|
713
|
+
} else if (envoy_api_v2_Cluster_has_cluster_type(cluster)) {
|
714
|
+
fields.emplace_back("cluster_type: <not printed>");
|
715
|
+
} else {
|
716
|
+
fields.emplace_back("<unknown type>");
|
717
|
+
}
|
718
|
+
// eds_cluster_config
|
719
|
+
const envoy_api_v2_Cluster_EdsClusterConfig* eds_cluster_config =
|
720
|
+
envoy_api_v2_Cluster_eds_cluster_config(cluster);
|
721
|
+
if (eds_cluster_config != nullptr) {
|
722
|
+
fields.emplace_back("eds_cluster_config {");
|
723
|
+
// eds_config
|
724
|
+
const struct envoy_api_v2_core_ConfigSource* eds_config =
|
725
|
+
envoy_api_v2_Cluster_EdsClusterConfig_eds_config(eds_cluster_config);
|
726
|
+
if (eds_config != nullptr) {
|
727
|
+
if (envoy_api_v2_core_ConfigSource_has_ads(eds_config)) {
|
728
|
+
fields.emplace_back(" eds_config { ads {} }");
|
729
|
+
} else {
|
730
|
+
fields.emplace_back(" eds_config: <non-ADS type>");
|
731
|
+
}
|
732
|
+
}
|
733
|
+
// service_name
|
734
|
+
AddStringField(" service_name",
|
735
|
+
envoy_api_v2_Cluster_EdsClusterConfig_service_name(
|
736
|
+
eds_cluster_config),
|
737
|
+
&fields);
|
738
|
+
fields.emplace_back("}");
|
739
|
+
}
|
740
|
+
// lb_policy
|
741
|
+
fields.emplace_back(
|
742
|
+
absl::StrCat("lb_policy: ", envoy_api_v2_Cluster_lb_policy(cluster)));
|
743
|
+
// lrs_server
|
744
|
+
const envoy_api_v2_core_ConfigSource* lrs_server =
|
745
|
+
envoy_api_v2_Cluster_lrs_server(cluster);
|
746
|
+
if (lrs_server != nullptr) {
|
747
|
+
if (envoy_api_v2_core_ConfigSource_has_self(lrs_server)) {
|
748
|
+
fields.emplace_back("lrs_server { self {} }");
|
749
|
+
} else {
|
750
|
+
fields.emplace_back("lrs_server: <non-self type>");
|
751
|
+
}
|
752
|
+
}
|
753
|
+
gpr_log(GPR_DEBUG, "[xds_client %p] Cluster: %s", client,
|
754
|
+
absl::StrJoin(fields, "\n").c_str());
|
755
|
+
}
|
756
|
+
}
|
757
|
+
|
758
|
+
void MaybeLogClusterLoadAssignment(
|
759
|
+
XdsClient* client, TraceFlag* tracer,
|
760
|
+
const envoy_api_v2_ClusterLoadAssignment* cla) {
|
761
|
+
if (GRPC_TRACE_FLAG_ENABLED(*tracer) &&
|
762
|
+
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
|
763
|
+
// TODO(roth): When we can upgrade upb, use upb textformat code to dump
|
764
|
+
// the raw proto instead of doing this manually.
|
765
|
+
std::vector<std::string> fields;
|
766
|
+
// cluster_name
|
767
|
+
AddStringField("cluster_name",
|
768
|
+
envoy_api_v2_ClusterLoadAssignment_cluster_name(cla),
|
769
|
+
&fields);
|
770
|
+
// endpoints
|
771
|
+
size_t num_localities;
|
772
|
+
const struct envoy_api_v2_endpoint_LocalityLbEndpoints* const*
|
773
|
+
locality_endpoints =
|
774
|
+
envoy_api_v2_ClusterLoadAssignment_endpoints(cla, &num_localities);
|
775
|
+
for (size_t i = 0; i < num_localities; ++i) {
|
776
|
+
const auto* locality_endpoint = locality_endpoints[i];
|
777
|
+
fields.emplace_back("endpoints {");
|
778
|
+
// locality
|
779
|
+
const auto* locality =
|
780
|
+
envoy_api_v2_endpoint_LocalityLbEndpoints_locality(locality_endpoint);
|
781
|
+
if (locality != nullptr) {
|
782
|
+
fields.emplace_back(" locality {");
|
783
|
+
AddLocalityField(2, locality, &fields);
|
784
|
+
fields.emplace_back(" }");
|
785
|
+
}
|
786
|
+
// lb_endpoints
|
787
|
+
size_t num_lb_endpoints;
|
788
|
+
const envoy_api_v2_endpoint_LbEndpoint* const* lb_endpoints =
|
789
|
+
envoy_api_v2_endpoint_LocalityLbEndpoints_lb_endpoints(
|
790
|
+
locality_endpoint, &num_lb_endpoints);
|
791
|
+
for (size_t j = 0; j < num_lb_endpoints; ++j) {
|
792
|
+
const auto* lb_endpoint = lb_endpoints[j];
|
793
|
+
fields.emplace_back(" lb_endpoints {");
|
794
|
+
// health_status
|
795
|
+
uint32_t health_status =
|
796
|
+
envoy_api_v2_endpoint_LbEndpoint_health_status(lb_endpoint);
|
797
|
+
if (health_status > 0) {
|
798
|
+
fields.emplace_back(
|
799
|
+
absl::StrCat(" health_status: ", health_status));
|
800
|
+
}
|
801
|
+
// endpoint
|
802
|
+
const envoy_api_v2_endpoint_Endpoint* endpoint =
|
803
|
+
envoy_api_v2_endpoint_LbEndpoint_endpoint(lb_endpoint);
|
804
|
+
if (endpoint != nullptr) {
|
805
|
+
fields.emplace_back(" endpoint {");
|
806
|
+
// address
|
807
|
+
const auto* address =
|
808
|
+
envoy_api_v2_endpoint_Endpoint_address(endpoint);
|
809
|
+
if (address != nullptr) {
|
810
|
+
fields.emplace_back(" address {");
|
811
|
+
// socket_address
|
812
|
+
const auto* socket_address =
|
813
|
+
envoy_api_v2_core_Address_socket_address(address);
|
814
|
+
if (socket_address != nullptr) {
|
815
|
+
fields.emplace_back(" socket_address {");
|
816
|
+
// address
|
817
|
+
AddStringField(
|
818
|
+
" address",
|
819
|
+
envoy_api_v2_core_SocketAddress_address(socket_address),
|
820
|
+
&fields);
|
821
|
+
// port_value
|
822
|
+
if (envoy_api_v2_core_SocketAddress_has_port_value(
|
823
|
+
socket_address)) {
|
824
|
+
fields.emplace_back(
|
825
|
+
absl::StrCat(" port_value: ",
|
826
|
+
envoy_api_v2_core_SocketAddress_port_value(
|
827
|
+
socket_address)));
|
828
|
+
} else {
|
829
|
+
fields.emplace_back(" <non-numeric port>");
|
830
|
+
}
|
831
|
+
fields.emplace_back(" }");
|
832
|
+
} else {
|
833
|
+
fields.emplace_back(" <non-socket address>");
|
834
|
+
}
|
835
|
+
fields.emplace_back(" }");
|
836
|
+
}
|
837
|
+
fields.emplace_back(" }");
|
838
|
+
}
|
839
|
+
fields.emplace_back(" }");
|
840
|
+
}
|
841
|
+
// load_balancing_weight
|
842
|
+
const google_protobuf_UInt32Value* lb_weight =
|
843
|
+
envoy_api_v2_endpoint_LocalityLbEndpoints_load_balancing_weight(
|
844
|
+
locality_endpoint);
|
845
|
+
if (lb_weight != nullptr) {
|
846
|
+
fields.emplace_back(
|
847
|
+
absl::StrCat(" load_balancing_weight { value: ",
|
848
|
+
google_protobuf_UInt32Value_value(lb_weight), " }"));
|
849
|
+
}
|
850
|
+
// priority
|
851
|
+
uint32_t priority =
|
852
|
+
envoy_api_v2_endpoint_LocalityLbEndpoints_priority(locality_endpoint);
|
853
|
+
if (priority > 0) {
|
854
|
+
fields.emplace_back(absl::StrCat(" priority: ", priority));
|
855
|
+
}
|
856
|
+
fields.emplace_back("}");
|
857
|
+
}
|
858
|
+
// policy
|
859
|
+
const envoy_api_v2_ClusterLoadAssignment_Policy* policy =
|
860
|
+
envoy_api_v2_ClusterLoadAssignment_policy(cla);
|
861
|
+
if (policy != nullptr) {
|
862
|
+
fields.emplace_back("policy {");
|
863
|
+
// drop_overloads
|
864
|
+
size_t num_drop_overloads;
|
865
|
+
const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* const*
|
866
|
+
drop_overloads =
|
867
|
+
envoy_api_v2_ClusterLoadAssignment_Policy_drop_overloads(
|
868
|
+
policy, &num_drop_overloads);
|
869
|
+
for (size_t i = 0; i < num_drop_overloads; ++i) {
|
870
|
+
auto* drop_overload = drop_overloads[i];
|
871
|
+
fields.emplace_back(" drop_overloads {");
|
872
|
+
// category
|
873
|
+
AddStringField(
|
874
|
+
" category",
|
875
|
+
envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_category(
|
876
|
+
drop_overload),
|
877
|
+
&fields);
|
878
|
+
// drop_percentage
|
879
|
+
const auto* drop_percentage =
|
880
|
+
envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(
|
881
|
+
drop_overload);
|
882
|
+
if (drop_percentage != nullptr) {
|
883
|
+
fields.emplace_back(" drop_percentage {");
|
884
|
+
fields.emplace_back(absl::StrCat(
|
885
|
+
" numerator: ",
|
886
|
+
envoy_type_FractionalPercent_numerator(drop_percentage)));
|
887
|
+
fields.emplace_back(absl::StrCat(
|
888
|
+
" denominator: ",
|
889
|
+
envoy_type_FractionalPercent_denominator(drop_percentage)));
|
890
|
+
fields.emplace_back(" }");
|
891
|
+
}
|
892
|
+
fields.emplace_back(" }");
|
893
|
+
}
|
894
|
+
// overprovisioning_factor
|
895
|
+
fields.emplace_back("}");
|
896
|
+
}
|
897
|
+
gpr_log(GPR_DEBUG, "[xds_client %p] ClusterLoadAssignment: %s", client,
|
898
|
+
absl::StrJoin(fields, "\n").c_str());
|
899
|
+
}
|
900
|
+
}
|
901
|
+
|
402
902
|
// Better match type has smaller value.
|
403
903
|
enum MatchType {
|
404
904
|
EXACT_MATCH,
|
@@ -449,11 +949,10 @@ MatchType DomainPatternMatchType(const std::string& domain_pattern) {
|
|
449
949
|
}
|
450
950
|
|
451
951
|
grpc_error* RouteConfigParse(
|
952
|
+
XdsClient* client, TraceFlag* tracer,
|
452
953
|
const envoy_api_v2_RouteConfiguration* route_config,
|
453
954
|
const std::string& expected_server_name, XdsApi::RdsUpdate* rds_update) {
|
454
|
-
|
455
|
-
size_t pos = expected_server_name.find(':');
|
456
|
-
std::string expected_host_name = expected_server_name.substr(0, pos);
|
955
|
+
MaybeLogRouteConfiguration(client, tracer, route_config);
|
457
956
|
// Get the virtual hosts.
|
458
957
|
size_t size;
|
459
958
|
const envoy_api_v2_route_VirtualHost* const* virtual_hosts =
|
@@ -490,7 +989,7 @@ grpc_error* RouteConfigParse(
|
|
490
989
|
continue;
|
491
990
|
}
|
492
991
|
// Skip if match fails.
|
493
|
-
if (!DomainMatch(match_type, domain_pattern,
|
992
|
+
if (!DomainMatch(match_type, domain_pattern, expected_server_name)) {
|
494
993
|
continue;
|
495
994
|
}
|
496
995
|
// Choose this match.
|
@@ -543,17 +1042,15 @@ grpc_error* RouteConfigParse(
|
|
543
1042
|
return GRPC_ERROR_NONE;
|
544
1043
|
}
|
545
1044
|
|
546
|
-
grpc_error* LdsResponseParse(
|
1045
|
+
grpc_error* LdsResponseParse(XdsClient* client, TraceFlag* tracer,
|
1046
|
+
const envoy_api_v2_DiscoveryResponse* response,
|
547
1047
|
const std::string& expected_server_name,
|
548
|
-
XdsApi::LdsUpdate
|
1048
|
+
absl::optional<XdsApi::LdsUpdate>* lds_update,
|
1049
|
+
upb_arena* arena) {
|
549
1050
|
// Get the resources from the response.
|
550
1051
|
size_t size;
|
551
1052
|
const google_protobuf_Any* const* resources =
|
552
1053
|
envoy_api_v2_DiscoveryResponse_resources(response, &size);
|
553
|
-
if (size < 1) {
|
554
|
-
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
555
|
-
"LDS response contains 0 resource.");
|
556
|
-
}
|
557
1054
|
for (size_t i = 0; i < size; ++i) {
|
558
1055
|
// Check the type_url of the resource.
|
559
1056
|
const upb_strview type_url = google_protobuf_Any_type_url(resources[i]);
|
@@ -593,14 +1090,11 @@ grpc_error* LdsResponseParse(const envoy_api_v2_DiscoveryResponse* response,
|
|
593
1090
|
envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_route_config(
|
594
1091
|
http_connection_manager);
|
595
1092
|
XdsApi::RdsUpdate rds_update;
|
596
|
-
grpc_error* error =
|
597
|
-
|
1093
|
+
grpc_error* error = RouteConfigParse(client, tracer, route_config,
|
1094
|
+
expected_server_name, &rds_update);
|
598
1095
|
if (error != GRPC_ERROR_NONE) return error;
|
599
|
-
lds_update->
|
600
|
-
|
601
|
-
envoy_api_v2_RouteConfiguration_name(route_config);
|
602
|
-
lds_update->route_config_name =
|
603
|
-
std::string(route_config_name.data, route_config_name.size);
|
1096
|
+
lds_update->emplace();
|
1097
|
+
(*lds_update)->rds_update.emplace(std::move(rds_update));
|
604
1098
|
return GRPC_ERROR_NONE;
|
605
1099
|
}
|
606
1100
|
// Validate that RDS must be used to get the route_config dynamically.
|
@@ -616,26 +1110,24 @@ grpc_error* LdsResponseParse(const envoy_api_v2_DiscoveryResponse* response,
|
|
616
1110
|
const upb_strview route_config_name =
|
617
1111
|
envoy_config_filter_network_http_connection_manager_v2_Rds_route_config_name(
|
618
1112
|
rds);
|
619
|
-
lds_update->
|
1113
|
+
lds_update->emplace();
|
1114
|
+
(*lds_update)->route_config_name =
|
620
1115
|
std::string(route_config_name.data, route_config_name.size);
|
621
1116
|
return GRPC_ERROR_NONE;
|
622
1117
|
}
|
623
|
-
return
|
624
|
-
"No listener found for expected server name.");
|
1118
|
+
return GRPC_ERROR_NONE;
|
625
1119
|
}
|
626
1120
|
|
627
|
-
grpc_error* RdsResponseParse(
|
1121
|
+
grpc_error* RdsResponseParse(XdsClient* client, TraceFlag* tracer,
|
1122
|
+
const envoy_api_v2_DiscoveryResponse* response,
|
628
1123
|
const std::string& expected_server_name,
|
629
1124
|
const std::string& expected_route_config_name,
|
630
|
-
XdsApi::RdsUpdate
|
1125
|
+
absl::optional<XdsApi::RdsUpdate>* rds_update,
|
1126
|
+
upb_arena* arena) {
|
631
1127
|
// Get the resources from the response.
|
632
1128
|
size_t size;
|
633
1129
|
const google_protobuf_Any* const* resources =
|
634
1130
|
envoy_api_v2_DiscoveryResponse_resources(response, &size);
|
635
|
-
if (size < 1) {
|
636
|
-
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
637
|
-
"RDS response contains 0 resource.");
|
638
|
-
}
|
639
1131
|
for (size_t i = 0; i < size; ++i) {
|
640
1132
|
// Check the type_url of the resource.
|
641
1133
|
const upb_strview type_url = google_protobuf_Any_type_url(resources[i]);
|
@@ -658,27 +1150,24 @@ grpc_error* RdsResponseParse(const envoy_api_v2_DiscoveryResponse* response,
|
|
658
1150
|
if (!upb_strview_eql(name, expected_name)) continue;
|
659
1151
|
// Parse the route_config.
|
660
1152
|
XdsApi::RdsUpdate local_rds_update;
|
661
|
-
grpc_error* error =
|
662
|
-
|
1153
|
+
grpc_error* error = RouteConfigParse(
|
1154
|
+
client, tracer, route_config, expected_server_name, &local_rds_update);
|
663
1155
|
if (error != GRPC_ERROR_NONE) return error;
|
664
|
-
|
1156
|
+
rds_update->emplace(std::move(local_rds_update));
|
665
1157
|
return GRPC_ERROR_NONE;
|
666
1158
|
}
|
667
|
-
return
|
668
|
-
"No route config found for expected name.");
|
1159
|
+
return GRPC_ERROR_NONE;
|
669
1160
|
}
|
670
1161
|
|
671
|
-
grpc_error* CdsResponseParse(
|
1162
|
+
grpc_error* CdsResponseParse(XdsClient* client, TraceFlag* tracer,
|
1163
|
+
const envoy_api_v2_DiscoveryResponse* response,
|
1164
|
+
const std::set<StringView>& expected_cluster_names,
|
672
1165
|
XdsApi::CdsUpdateMap* cds_update_map,
|
673
1166
|
upb_arena* arena) {
|
674
1167
|
// Get the resources from the response.
|
675
1168
|
size_t size;
|
676
1169
|
const google_protobuf_Any* const* resources =
|
677
1170
|
envoy_api_v2_DiscoveryResponse_resources(response, &size);
|
678
|
-
if (size < 1) {
|
679
|
-
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
680
|
-
"CDS response contains 0 resource.");
|
681
|
-
}
|
682
1171
|
// Parse all the resources in the CDS response.
|
683
1172
|
for (size_t i = 0; i < size; ++i) {
|
684
1173
|
XdsApi::CdsUpdate cds_update;
|
@@ -694,6 +1183,14 @@ grpc_error* CdsResponseParse(const envoy_api_v2_DiscoveryResponse* response,
|
|
694
1183
|
if (cluster == nullptr) {
|
695
1184
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Can't decode cluster.");
|
696
1185
|
}
|
1186
|
+
MaybeLogCluster(client, tracer, cluster);
|
1187
|
+
// Ignore unexpected cluster names.
|
1188
|
+
upb_strview cluster_name = envoy_api_v2_Cluster_name(cluster);
|
1189
|
+
StringView cluster_name_strview(cluster_name.data, cluster_name.size);
|
1190
|
+
if (expected_cluster_names.find(cluster_name_strview) ==
|
1191
|
+
expected_cluster_names.end()) {
|
1192
|
+
continue;
|
1193
|
+
}
|
697
1194
|
// Check the cluster_discovery_type.
|
698
1195
|
if (!envoy_api_v2_Cluster_has_type(cluster)) {
|
699
1196
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("DiscoveryType not found.");
|
@@ -732,7 +1229,6 @@ grpc_error* CdsResponseParse(const envoy_api_v2_DiscoveryResponse* response,
|
|
732
1229
|
}
|
733
1230
|
cds_update.lrs_load_reporting_server_name.emplace("");
|
734
1231
|
}
|
735
|
-
upb_strview cluster_name = envoy_api_v2_Cluster_name(cluster);
|
736
1232
|
cds_update_map->emplace(std::string(cluster_name.data, cluster_name.size),
|
737
1233
|
std::move(cds_update));
|
738
1234
|
}
|
@@ -814,7 +1310,7 @@ grpc_error* LocalityParse(
|
|
814
1310
|
|
815
1311
|
grpc_error* DropParseAndAppend(
|
816
1312
|
const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* drop_overload,
|
817
|
-
XdsApi::DropConfig* drop_config
|
1313
|
+
XdsApi::DropConfig* drop_config) {
|
818
1314
|
// Get the category.
|
819
1315
|
upb_strview category =
|
820
1316
|
envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_category(
|
@@ -845,13 +1341,13 @@ grpc_error* DropParseAndAppend(
|
|
845
1341
|
}
|
846
1342
|
// Cap numerator to 1000000.
|
847
1343
|
numerator = GPR_MIN(numerator, 1000000);
|
848
|
-
if (numerator == 1000000) *drop_all = true;
|
849
1344
|
drop_config->AddCategory(std::string(category.data, category.size),
|
850
1345
|
numerator);
|
851
1346
|
return GRPC_ERROR_NONE;
|
852
1347
|
}
|
853
1348
|
|
854
|
-
grpc_error*
|
1349
|
+
grpc_error* EdsResponseParse(
|
1350
|
+
XdsClient* client, TraceFlag* tracer,
|
855
1351
|
const envoy_api_v2_DiscoveryResponse* response,
|
856
1352
|
const std::set<StringView>& expected_eds_service_names,
|
857
1353
|
XdsApi::EdsUpdateMap* eds_update_map, upb_arena* arena) {
|
@@ -859,10 +1355,6 @@ grpc_error* EdsResponsedParse(
|
|
859
1355
|
size_t size;
|
860
1356
|
const google_protobuf_Any* const* resources =
|
861
1357
|
envoy_api_v2_DiscoveryResponse_resources(response, &size);
|
862
|
-
if (size < 1) {
|
863
|
-
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
864
|
-
"EDS response contains 0 resource.");
|
865
|
-
}
|
866
1358
|
for (size_t i = 0; i < size; ++i) {
|
867
1359
|
XdsApi::EdsUpdate eds_update;
|
868
1360
|
// Check the type_url of the resource.
|
@@ -881,6 +1373,7 @@ grpc_error* EdsResponsedParse(
|
|
881
1373
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
882
1374
|
"Can't parse cluster_load_assignment.");
|
883
1375
|
}
|
1376
|
+
MaybeLogClusterLoadAssignment(client, tracer, cluster_load_assignment);
|
884
1377
|
// Check the cluster name (which actually means eds_service_name). Ignore
|
885
1378
|
// unexpected names.
|
886
1379
|
upb_strview cluster_name = envoy_api_v2_ClusterLoadAssignment_cluster_name(
|
@@ -903,6 +1396,14 @@ grpc_error* EdsResponsedParse(
|
|
903
1396
|
if (locality.lb_weight == 0) continue;
|
904
1397
|
eds_update.priority_list_update.Add(locality);
|
905
1398
|
}
|
1399
|
+
for (uint32_t priority = 0;
|
1400
|
+
priority < eds_update.priority_list_update.size(); ++priority) {
|
1401
|
+
auto* locality_map = eds_update.priority_list_update.Find(priority);
|
1402
|
+
if (locality_map == nullptr || locality_map->size() == 0) {
|
1403
|
+
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1404
|
+
"EDS update includes sparse priority list");
|
1405
|
+
}
|
1406
|
+
}
|
906
1407
|
// Get the drop config.
|
907
1408
|
eds_update.drop_config = MakeRefCounted<XdsApi::DropConfig>();
|
908
1409
|
const envoy_api_v2_ClusterLoadAssignment_Policy* policy =
|
@@ -915,13 +1416,13 @@ grpc_error* EdsResponsedParse(
|
|
915
1416
|
policy, &drop_size);
|
916
1417
|
for (size_t j = 0; j < drop_size; ++j) {
|
917
1418
|
grpc_error* error =
|
918
|
-
DropParseAndAppend(drop_overload[j], eds_update.drop_config.get()
|
919
|
-
&eds_update.drop_all);
|
1419
|
+
DropParseAndAppend(drop_overload[j], eds_update.drop_config.get());
|
920
1420
|
if (error != GRPC_ERROR_NONE) return error;
|
921
1421
|
}
|
922
1422
|
}
|
923
1423
|
// Validate the update content.
|
924
|
-
if (eds_update.priority_list_update.empty() &&
|
1424
|
+
if (eds_update.priority_list_update.empty() &&
|
1425
|
+
!eds_update.drop_config->drop_all()) {
|
925
1426
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
926
1427
|
"EDS response doesn't contain any valid "
|
927
1428
|
"locality but doesn't require to drop all calls.");
|
@@ -937,8 +1438,10 @@ grpc_error* EdsResponsedParse(
|
|
937
1438
|
grpc_error* XdsApi::ParseAdsResponse(
|
938
1439
|
const grpc_slice& encoded_response, const std::string& expected_server_name,
|
939
1440
|
const std::string& expected_route_config_name,
|
1441
|
+
const std::set<StringView>& expected_cluster_names,
|
940
1442
|
const std::set<StringView>& expected_eds_service_names,
|
941
|
-
LdsUpdate
|
1443
|
+
absl::optional<LdsUpdate>* lds_update,
|
1444
|
+
absl::optional<RdsUpdate>* rds_update, CdsUpdateMap* cds_update_map,
|
942
1445
|
EdsUpdateMap* eds_update_map, std::string* version, std::string* nonce,
|
943
1446
|
std::string* type_url) {
|
944
1447
|
upb::Arena arena;
|
@@ -953,6 +1456,7 @@ grpc_error* XdsApi::ParseAdsResponse(
|
|
953
1456
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
954
1457
|
"Can't decode the whole response.");
|
955
1458
|
}
|
1459
|
+
MaybeLogDiscoveryResponse(client_, tracer_, response);
|
956
1460
|
// Record the type_url, the version_info, and the nonce of the response.
|
957
1461
|
upb_strview type_url_strview =
|
958
1462
|
envoy_api_v2_DiscoveryResponse_type_url(response);
|
@@ -964,17 +1468,19 @@ grpc_error* XdsApi::ParseAdsResponse(
|
|
964
1468
|
*nonce = std::string(nonce_strview.data, nonce_strview.size);
|
965
1469
|
// Parse the response according to the resource type.
|
966
1470
|
if (*type_url == kLdsTypeUrl) {
|
967
|
-
return LdsResponseParse(response, expected_server_name,
|
968
|
-
arena.ptr());
|
1471
|
+
return LdsResponseParse(client_, tracer_, response, expected_server_name,
|
1472
|
+
lds_update, arena.ptr());
|
969
1473
|
} else if (*type_url == kRdsTypeUrl) {
|
970
|
-
return RdsResponseParse(response, expected_server_name,
|
1474
|
+
return RdsResponseParse(client_, tracer_, response, expected_server_name,
|
971
1475
|
expected_route_config_name, rds_update,
|
972
1476
|
arena.ptr());
|
973
1477
|
} else if (*type_url == kCdsTypeUrl) {
|
974
|
-
return CdsResponseParse(response,
|
1478
|
+
return CdsResponseParse(client_, tracer_, response, expected_cluster_names,
|
1479
|
+
cds_update_map, arena.ptr());
|
975
1480
|
} else if (*type_url == kEdsTypeUrl) {
|
976
|
-
return
|
977
|
-
|
1481
|
+
return EdsResponseParse(client_, tracer_, response,
|
1482
|
+
expected_eds_service_names, eds_update_map,
|
1483
|
+
arena.ptr());
|
978
1484
|
} else {
|
979
1485
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
980
1486
|
"Unsupported ADS resource type.");
|
@@ -983,6 +1489,121 @@ grpc_error* XdsApi::ParseAdsResponse(
|
|
983
1489
|
|
984
1490
|
namespace {
|
985
1491
|
|
1492
|
+
void MaybeLogLrsRequest(
|
1493
|
+
XdsClient* client, TraceFlag* tracer,
|
1494
|
+
const envoy_service_load_stats_v2_LoadStatsRequest* request) {
|
1495
|
+
if (GRPC_TRACE_FLAG_ENABLED(*tracer) &&
|
1496
|
+
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
|
1497
|
+
// TODO(roth): When we can upgrade upb, use upb textformat code to dump
|
1498
|
+
// the raw proto instead of doing this manually.
|
1499
|
+
std::vector<std::string> fields;
|
1500
|
+
// node
|
1501
|
+
const auto* node =
|
1502
|
+
envoy_service_load_stats_v2_LoadStatsRequest_node(request);
|
1503
|
+
if (node != nullptr) {
|
1504
|
+
AddNodeLogFields(node, &fields);
|
1505
|
+
}
|
1506
|
+
// cluster_stats
|
1507
|
+
size_t num_cluster_stats;
|
1508
|
+
const struct envoy_api_v2_endpoint_ClusterStats* const* cluster_stats =
|
1509
|
+
envoy_service_load_stats_v2_LoadStatsRequest_cluster_stats(
|
1510
|
+
request, &num_cluster_stats);
|
1511
|
+
for (size_t i = 0; i < num_cluster_stats; ++i) {
|
1512
|
+
const auto* cluster_stat = cluster_stats[i];
|
1513
|
+
fields.emplace_back("cluster_stats {");
|
1514
|
+
// cluster_name
|
1515
|
+
AddStringField(
|
1516
|
+
" cluster_name",
|
1517
|
+
envoy_api_v2_endpoint_ClusterStats_cluster_name(cluster_stat),
|
1518
|
+
&fields);
|
1519
|
+
// cluster_service_name
|
1520
|
+
AddStringField(
|
1521
|
+
" cluster_service_name",
|
1522
|
+
envoy_api_v2_endpoint_ClusterStats_cluster_service_name(cluster_stat),
|
1523
|
+
&fields);
|
1524
|
+
// upstream_locality_stats
|
1525
|
+
size_t num_stats;
|
1526
|
+
const envoy_api_v2_endpoint_UpstreamLocalityStats* const* stats =
|
1527
|
+
envoy_api_v2_endpoint_ClusterStats_upstream_locality_stats(
|
1528
|
+
cluster_stat, &num_stats);
|
1529
|
+
for (size_t j = 0; j < num_stats; ++j) {
|
1530
|
+
const auto* stat = stats[j];
|
1531
|
+
fields.emplace_back(" upstream_locality_stats {");
|
1532
|
+
// locality
|
1533
|
+
const auto* locality =
|
1534
|
+
envoy_api_v2_endpoint_UpstreamLocalityStats_locality(stat);
|
1535
|
+
if (locality != nullptr) {
|
1536
|
+
fields.emplace_back(" locality {");
|
1537
|
+
AddLocalityField(3, locality, &fields);
|
1538
|
+
fields.emplace_back(" }");
|
1539
|
+
}
|
1540
|
+
// total_successful_requests
|
1541
|
+
fields.emplace_back(absl::StrCat(
|
1542
|
+
" total_successful_requests: ",
|
1543
|
+
envoy_api_v2_endpoint_UpstreamLocalityStats_total_successful_requests(
|
1544
|
+
stat)));
|
1545
|
+
// total_requests_in_progress
|
1546
|
+
fields.emplace_back(absl::StrCat(
|
1547
|
+
" total_requests_in_progress: ",
|
1548
|
+
envoy_api_v2_endpoint_UpstreamLocalityStats_total_requests_in_progress(
|
1549
|
+
stat)));
|
1550
|
+
// total_error_requests
|
1551
|
+
fields.emplace_back(absl::StrCat(
|
1552
|
+
" total_error_requests: ",
|
1553
|
+
envoy_api_v2_endpoint_UpstreamLocalityStats_total_error_requests(
|
1554
|
+
stat)));
|
1555
|
+
// total_issued_requests
|
1556
|
+
fields.emplace_back(absl::StrCat(
|
1557
|
+
" total_issued_requests: ",
|
1558
|
+
envoy_api_v2_endpoint_UpstreamLocalityStats_total_issued_requests(
|
1559
|
+
stat)));
|
1560
|
+
fields.emplace_back(" }");
|
1561
|
+
}
|
1562
|
+
// total_dropped_requests
|
1563
|
+
fields.emplace_back(absl::StrCat(
|
1564
|
+
" total_dropped_requests: ",
|
1565
|
+
envoy_api_v2_endpoint_ClusterStats_total_dropped_requests(
|
1566
|
+
cluster_stat)));
|
1567
|
+
// dropped_requests
|
1568
|
+
size_t num_drops;
|
1569
|
+
const envoy_api_v2_endpoint_ClusterStats_DroppedRequests* const* drops =
|
1570
|
+
envoy_api_v2_endpoint_ClusterStats_dropped_requests(cluster_stat,
|
1571
|
+
&num_drops);
|
1572
|
+
for (size_t j = 0; j < num_drops; ++j) {
|
1573
|
+
const auto* drop = drops[j];
|
1574
|
+
fields.emplace_back(" dropped_requests {");
|
1575
|
+
// category
|
1576
|
+
AddStringField(
|
1577
|
+
" category",
|
1578
|
+
envoy_api_v2_endpoint_ClusterStats_DroppedRequests_category(drop),
|
1579
|
+
&fields);
|
1580
|
+
// dropped_count
|
1581
|
+
fields.emplace_back(absl::StrCat(
|
1582
|
+
" dropped_count: ",
|
1583
|
+
envoy_api_v2_endpoint_ClusterStats_DroppedRequests_dropped_count(
|
1584
|
+
drop)));
|
1585
|
+
fields.emplace_back(" }");
|
1586
|
+
}
|
1587
|
+
// load_report_interval
|
1588
|
+
const auto* load_report_interval =
|
1589
|
+
envoy_api_v2_endpoint_ClusterStats_load_report_interval(cluster_stat);
|
1590
|
+
if (load_report_interval != nullptr) {
|
1591
|
+
fields.emplace_back(" load_report_interval {");
|
1592
|
+
fields.emplace_back(absl::StrCat(
|
1593
|
+
" seconds: ",
|
1594
|
+
google_protobuf_Duration_seconds(load_report_interval)));
|
1595
|
+
fields.emplace_back(
|
1596
|
+
absl::StrCat(" nanos: ",
|
1597
|
+
google_protobuf_Duration_nanos(load_report_interval)));
|
1598
|
+
fields.emplace_back(" }");
|
1599
|
+
}
|
1600
|
+
fields.emplace_back("}");
|
1601
|
+
}
|
1602
|
+
gpr_log(GPR_DEBUG, "[xds_client %p] constructed LRS request: %s", client,
|
1603
|
+
absl::StrJoin(fields, "\n").c_str());
|
1604
|
+
}
|
1605
|
+
}
|
1606
|
+
|
986
1607
|
grpc_slice SerializeLrsRequest(
|
987
1608
|
const envoy_service_load_stats_v2_LoadStatsRequest* request,
|
988
1609
|
upb_arena* arena) {
|
@@ -1005,6 +1626,7 @@ grpc_slice XdsApi::CreateLrsInitialRequest(const std::string& server_name) {
|
|
1005
1626
|
arena.ptr());
|
1006
1627
|
PopulateNode(arena.ptr(), node_, build_version_, user_agent_name_,
|
1007
1628
|
server_name, node_msg);
|
1629
|
+
MaybeLogLrsRequest(client_, tracer_, request);
|
1008
1630
|
return SerializeLrsRequest(request, arena.ptr());
|
1009
1631
|
}
|
1010
1632
|
|
@@ -1117,6 +1739,7 @@ grpc_slice XdsApi::CreateLrsRequest(
|
|
1117
1739
|
google_protobuf_Duration_set_seconds(load_report_interval, timespec.tv_sec);
|
1118
1740
|
google_protobuf_Duration_set_nanos(load_report_interval, timespec.tv_nsec);
|
1119
1741
|
}
|
1742
|
+
MaybeLogLrsRequest(client_, tracer_, request);
|
1120
1743
|
return SerializeLrsRequest(request, arena.ptr());
|
1121
1744
|
}
|
1122
1745
|
|