grpc 1.16.0 → 1.17.0.pre1
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 +299 -133
- data/include/grpc/grpc.h +11 -1
- data/include/grpc/grpc_posix.h +0 -8
- data/include/grpc/impl/codegen/grpc_types.h +3 -0
- data/src/core/ext/filters/client_channel/client_channel.cc +336 -345
- data/src/core/ext/filters/client_channel/client_channel.h +6 -2
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +3 -1
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +0 -7
- data/src/core/ext/filters/client_channel/health/health.pb.c +23 -0
- data/src/core/ext/filters/client_channel/health/health.pb.h +73 -0
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +652 -0
- data/src/core/ext/filters/client_channel/health/health_check_client.h +173 -0
- data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +2 -1
- data/src/core/ext/filters/client_channel/http_proxy.cc +1 -1
- data/src/core/ext/filters/client_channel/lb_policy.h +17 -14
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +15 -11
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +21 -15
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +18 -10
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +12 -9
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +19 -8
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +1832 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.h +36 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +36 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +107 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc +85 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h +72 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +307 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +89 -0
- data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
- data/src/core/ext/filters/client_channel/lb_policy_registry.cc +5 -0
- data/src/core/ext/filters/client_channel/lb_policy_registry.h +4 -0
- data/src/core/ext/filters/client_channel/parse_address.h +1 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +19 -22
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +41 -39
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +3 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +4 -1
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +15 -2
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +5 -1
- data/src/core/ext/filters/client_channel/resolver_factory.h +1 -1
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +384 -0
- data/src/core/ext/filters/client_channel/resolver_result_parsing.h +146 -0
- data/src/core/ext/filters/client_channel/subchannel.cc +361 -103
- data/src/core/ext/filters/client_channel/subchannel.h +14 -8
- data/src/core/ext/filters/deadline/deadline_filter.cc +19 -23
- data/src/core/ext/filters/deadline/deadline_filter.h +9 -13
- data/src/core/ext/filters/http/client/http_client_filter.cc +29 -19
- data/src/core/ext/filters/http/client_authority_filter.cc +2 -3
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +28 -16
- data/src/core/ext/filters/http/server/http_server_filter.cc +31 -20
- data/src/core/ext/filters/message_size/message_size_filter.cc +50 -45
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +13 -6
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +1 -1
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +58 -8
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +175 -173
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +2 -1
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -10
- data/src/core/ext/transport/chttp2/transport/frame_data.h +10 -12
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +28 -25
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +0 -12
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +12 -9
- data/src/core/ext/transport/chttp2/transport/internal.h +109 -94
- data/src/core/ext/transport/chttp2/transport/parsing.cc +4 -2
- data/src/core/ext/transport/inproc/inproc_transport.cc +280 -300
- data/src/core/lib/channel/channel_stack.cc +5 -4
- data/src/core/lib/channel/channel_stack.h +4 -4
- data/src/core/lib/channel/channel_stack_builder.cc +14 -2
- data/src/core/lib/channel/channel_stack_builder.h +8 -0
- data/src/core/lib/channel/channel_trace.cc +6 -2
- data/src/core/lib/channel/channelz.cc +137 -5
- data/src/core/lib/channel/channelz.h +32 -6
- data/src/core/lib/channel/channelz_registry.cc +134 -28
- data/src/core/lib/channel/channelz_registry.h +25 -3
- data/src/core/lib/channel/context.h +4 -4
- data/src/core/lib/channel/handshaker.cc +7 -6
- data/src/core/lib/channel/handshaker.h +7 -8
- data/src/core/lib/channel/handshaker_factory.cc +3 -2
- data/src/core/lib/channel/handshaker_factory.h +2 -0
- data/src/core/lib/channel/handshaker_registry.cc +6 -2
- data/src/core/lib/channel/handshaker_registry.h +1 -0
- data/src/core/lib/gpr/arena.cc +84 -37
- data/src/core/lib/gpr/arena.h +2 -0
- data/src/core/lib/gpr/mpscq.h +4 -2
- data/src/core/lib/gprpp/inlined_vector.h +8 -0
- data/src/core/lib/gprpp/ref_counted.h +105 -18
- data/src/core/lib/gprpp/ref_counted_ptr.h +11 -0
- data/src/core/lib/http/httpcli_security_connector.cc +7 -4
- data/src/core/lib/iomgr/call_combiner.cc +2 -0
- data/src/core/lib/iomgr/call_combiner.h +2 -2
- data/src/core/lib/iomgr/closure.h +1 -0
- data/src/core/lib/iomgr/error.cc +16 -31
- data/src/core/lib/iomgr/error.h +29 -4
- data/src/core/lib/iomgr/error_internal.h +0 -2
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +7 -3
- data/src/core/lib/iomgr/ev_posix.cc +0 -2
- data/src/core/lib/iomgr/polling_entity.h +4 -4
- data/src/core/lib/iomgr/resource_quota.cc +64 -10
- data/src/core/lib/iomgr/resource_quota.h +21 -6
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +11 -5
- data/src/core/lib/iomgr/tcp_client_custom.cc +14 -3
- data/src/core/lib/iomgr/tcp_client_posix.cc +2 -0
- data/src/core/lib/iomgr/tcp_posix.cc +4 -2
- data/src/core/lib/iomgr/timer_manager.cc +1 -1
- data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +3 -4
- data/src/core/lib/security/context/security_context.cc +20 -13
- data/src/core/lib/security/context/security_context.h +27 -19
- data/src/core/lib/security/credentials/alts/alts_credentials.cc +1 -1
- data/src/core/lib/security/credentials/credentials.h +2 -2
- data/src/core/lib/security/credentials/fake/fake_credentials.cc +1 -0
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +39 -54
- data/src/core/lib/security/credentials/google_default/google_default_credentials.h +3 -2
- data/src/core/lib/security/credentials/local/local_credentials.cc +1 -1
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +1 -2
- data/src/core/lib/security/credentials/ssl/ssl_credentials.h +2 -0
- data/src/core/lib/security/security_connector/{alts_security_connector.cc → alts/alts_security_connector.cc} +10 -9
- data/src/core/lib/security/security_connector/{alts_security_connector.h → alts/alts_security_connector.h} +3 -3
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +310 -0
- data/src/core/lib/security/security_connector/fake/fake_security_connector.h +42 -0
- data/src/core/lib/security/security_connector/{local_security_connector.cc → local/local_security_connector.cc} +4 -3
- data/src/core/lib/security/security_connector/{local_security_connector.h → local/local_security_connector.h} +3 -3
- data/src/core/lib/security/security_connector/security_connector.cc +4 -1039
- data/src/core/lib/security/security_connector/security_connector.h +6 -114
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +474 -0
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +77 -0
- data/src/core/lib/security/security_connector/ssl_utils.cc +345 -0
- data/src/core/lib/security/security_connector/ssl_utils.h +93 -0
- data/src/core/lib/security/transport/client_auth_filter.cc +28 -17
- data/src/core/lib/security/transport/secure_endpoint.cc +51 -41
- data/src/core/lib/security/transport/security_handshaker.cc +6 -7
- data/src/core/lib/security/transport/server_auth_filter.cc +39 -31
- data/src/core/lib/surface/call.cc +100 -80
- data/src/core/lib/surface/call.h +4 -0
- data/src/core/lib/surface/channel.cc +27 -13
- data/src/core/lib/surface/channel.h +4 -3
- data/src/core/lib/surface/completion_queue.cc +8 -1
- data/src/core/lib/surface/init.cc +1 -0
- data/src/core/lib/surface/server.cc +111 -46
- data/src/core/lib/surface/server.h +16 -2
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/error_utils.cc +4 -2
- data/src/core/lib/transport/metadata.cc +3 -2
- data/src/core/lib/transport/metadata.h +3 -2
- data/src/core/lib/transport/metadata_batch.cc +1 -0
- data/src/core/lib/transport/metadata_batch.h +4 -2
- data/src/core/lib/transport/static_metadata.cc +225 -221
- data/src/core/lib/transport/static_metadata.h +74 -71
- data/src/core/lib/transport/transport.h +44 -26
- data/src/core/{ext/filters/client_channel → lib/uri}/uri_parser.cc +1 -1
- data/src/core/{ext/filters/client_channel → lib/uri}/uri_parser.h +3 -3
- data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -4
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +356 -77
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +46 -36
- data/src/core/tsi/alts/handshaker/alts_shared_resource.cc +83 -0
- data/src/core/tsi/alts/handshaker/alts_shared_resource.h +73 -0
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +122 -175
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +33 -22
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h +38 -10
- data/src/core/tsi/transport_security.cc +18 -1
- data/src/core/tsi/transport_security.h +2 -1
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -3
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/pb/codegen/grpc/testing/package_options.proto +28 -0
- data/src/ruby/spec/pb/codegen/package_option_spec.rb +2 -3
- metadata +58 -40
- data/src/core/ext/filters/client_channel/method_params.cc +0 -178
- data/src/core/ext/filters/client_channel/method_params.h +0 -78
- data/src/core/tsi/alts/handshaker/alts_tsi_event.cc +0 -75
- data/src/core/tsi/alts/handshaker/alts_tsi_event.h +0 -93
- data/src/core/tsi/alts_transport_security.cc +0 -65
- data/src/core/tsi/alts_transport_security.h +0 -47
@@ -20,9 +20,9 @@
|
|
20
20
|
#include <grpc/support/port_platform.h>
|
21
21
|
|
22
22
|
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
|
23
|
-
#include "src/core/ext/filters/client_channel/uri_parser.h"
|
24
23
|
#include "src/core/lib/channel/channel_args.h"
|
25
24
|
#include "src/core/lib/gprpp/ref_counted.h"
|
25
|
+
#include "src/core/lib/uri/uri_parser.h"
|
26
26
|
|
27
27
|
#define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \
|
28
28
|
"grpc.fake_resolver.response_generator"
|
@@ -61,6 +61,10 @@ class FakeResolverResponseGenerator
|
|
61
61
|
// returning a null result with no error).
|
62
62
|
void SetFailure();
|
63
63
|
|
64
|
+
// Same as SetFailure(), but instead of returning the error
|
65
|
+
// immediately, waits for the next call to RequestReresolutionLocked().
|
66
|
+
void SetFailureOnReresolution();
|
67
|
+
|
64
68
|
// Returns a channel arg containing \a generator.
|
65
69
|
static grpc_arg MakeChannelArg(FakeResolverResponseGenerator* generator);
|
66
70
|
|
@@ -24,11 +24,11 @@
|
|
24
24
|
#include <grpc/support/string_util.h>
|
25
25
|
|
26
26
|
#include "src/core/ext/filters/client_channel/resolver.h"
|
27
|
-
#include "src/core/ext/filters/client_channel/uri_parser.h"
|
28
27
|
#include "src/core/lib/gprpp/abstract.h"
|
29
28
|
#include "src/core/lib/gprpp/memory.h"
|
30
29
|
#include "src/core/lib/gprpp/orphanable.h"
|
31
30
|
#include "src/core/lib/iomgr/pollset_set.h"
|
31
|
+
#include "src/core/lib/uri/uri_parser.h"
|
32
32
|
|
33
33
|
namespace grpc_core {
|
34
34
|
|
@@ -0,0 +1,384 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2018 gRPC authors.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include <grpc/support/port_platform.h>
|
20
|
+
|
21
|
+
#include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
|
22
|
+
|
23
|
+
#include <ctype.h>
|
24
|
+
#include <stdio.h>
|
25
|
+
#include <string.h>
|
26
|
+
|
27
|
+
#include <grpc/support/alloc.h>
|
28
|
+
#include <grpc/support/log.h>
|
29
|
+
#include <grpc/support/string_util.h>
|
30
|
+
|
31
|
+
#include "src/core/ext/filters/client_channel/client_channel.h"
|
32
|
+
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
|
33
|
+
#include "src/core/lib/channel/status_util.h"
|
34
|
+
#include "src/core/lib/gpr/string.h"
|
35
|
+
#include "src/core/lib/gprpp/memory.h"
|
36
|
+
|
37
|
+
// As per the retry design, we do not allow more than 5 retry attempts.
|
38
|
+
#define MAX_MAX_RETRY_ATTEMPTS 5
|
39
|
+
|
40
|
+
namespace grpc_core {
|
41
|
+
namespace internal {
|
42
|
+
|
43
|
+
namespace {
|
44
|
+
|
45
|
+
// Converts string format from JSON to proto.
|
46
|
+
grpc_core::UniquePtr<char> ConvertCamelToSnake(const char* camel) {
|
47
|
+
const size_t size = strlen(camel);
|
48
|
+
char* snake = static_cast<char*>(gpr_malloc(size * 2));
|
49
|
+
size_t j = 0;
|
50
|
+
for (size_t i = 0; i < size; ++i) {
|
51
|
+
if (isupper(camel[i])) {
|
52
|
+
snake[j++] = '_';
|
53
|
+
snake[j++] = tolower(camel[i]);
|
54
|
+
} else {
|
55
|
+
snake[j++] = camel[i];
|
56
|
+
}
|
57
|
+
}
|
58
|
+
snake[j] = '\0';
|
59
|
+
return grpc_core::UniquePtr<char>(snake);
|
60
|
+
}
|
61
|
+
|
62
|
+
} // namespace
|
63
|
+
|
64
|
+
ProcessedResolverResult::ProcessedResolverResult(
|
65
|
+
const grpc_channel_args* resolver_result, bool parse_retry) {
|
66
|
+
ProcessServiceConfig(resolver_result, parse_retry);
|
67
|
+
// If no LB config was found above, just find the LB policy name then.
|
68
|
+
if (lb_policy_config_ == nullptr) ProcessLbPolicyName(resolver_result);
|
69
|
+
}
|
70
|
+
|
71
|
+
void ProcessedResolverResult::ProcessServiceConfig(
|
72
|
+
const grpc_channel_args* resolver_result, bool parse_retry) {
|
73
|
+
const grpc_arg* channel_arg =
|
74
|
+
grpc_channel_args_find(resolver_result, GRPC_ARG_SERVICE_CONFIG);
|
75
|
+
const char* service_config_json = grpc_channel_arg_get_string(channel_arg);
|
76
|
+
if (service_config_json != nullptr) {
|
77
|
+
service_config_json_.reset(gpr_strdup(service_config_json));
|
78
|
+
service_config_ = grpc_core::ServiceConfig::Create(service_config_json);
|
79
|
+
if (service_config_ != nullptr) {
|
80
|
+
if (parse_retry) {
|
81
|
+
channel_arg =
|
82
|
+
grpc_channel_args_find(resolver_result, GRPC_ARG_SERVER_URI);
|
83
|
+
const char* server_uri = grpc_channel_arg_get_string(channel_arg);
|
84
|
+
GPR_ASSERT(server_uri != nullptr);
|
85
|
+
grpc_uri* uri = grpc_uri_parse(server_uri, true);
|
86
|
+
GPR_ASSERT(uri->path[0] != '\0');
|
87
|
+
server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path;
|
88
|
+
service_config_->ParseGlobalParams(ParseServiceConfig, this);
|
89
|
+
grpc_uri_destroy(uri);
|
90
|
+
} else {
|
91
|
+
service_config_->ParseGlobalParams(ParseServiceConfig, this);
|
92
|
+
}
|
93
|
+
method_params_table_ = service_config_->CreateMethodConfigTable(
|
94
|
+
ClientChannelMethodParams::CreateFromJson);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
void ProcessedResolverResult::ProcessLbPolicyName(
|
100
|
+
const grpc_channel_args* resolver_result) {
|
101
|
+
const char* lb_policy_name = nullptr;
|
102
|
+
// Prefer the LB policy name found in the service config. Note that this is
|
103
|
+
// checking the deprecated loadBalancingPolicy field, rather than the new
|
104
|
+
// loadBalancingConfig field.
|
105
|
+
if (service_config_ != nullptr) {
|
106
|
+
lb_policy_name = service_config_->GetLoadBalancingPolicyName();
|
107
|
+
}
|
108
|
+
// Otherwise, find the LB policy name set by the client API.
|
109
|
+
if (lb_policy_name == nullptr) {
|
110
|
+
const grpc_arg* channel_arg =
|
111
|
+
grpc_channel_args_find(resolver_result, GRPC_ARG_LB_POLICY_NAME);
|
112
|
+
lb_policy_name = grpc_channel_arg_get_string(channel_arg);
|
113
|
+
}
|
114
|
+
// Special case: If at least one balancer address is present, we use
|
115
|
+
// the grpclb policy, regardless of what the resolver has returned.
|
116
|
+
const grpc_arg* channel_arg =
|
117
|
+
grpc_channel_args_find(resolver_result, GRPC_ARG_LB_ADDRESSES);
|
118
|
+
if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) {
|
119
|
+
grpc_lb_addresses* addresses =
|
120
|
+
static_cast<grpc_lb_addresses*>(channel_arg->value.pointer.p);
|
121
|
+
if (grpc_lb_addresses_contains_balancer_address(*addresses)) {
|
122
|
+
if (lb_policy_name != nullptr &&
|
123
|
+
gpr_stricmp(lb_policy_name, "grpclb") != 0) {
|
124
|
+
gpr_log(GPR_INFO,
|
125
|
+
"resolver requested LB policy %s but provided at least one "
|
126
|
+
"balancer address -- forcing use of grpclb LB policy",
|
127
|
+
lb_policy_name);
|
128
|
+
}
|
129
|
+
lb_policy_name = "grpclb";
|
130
|
+
}
|
131
|
+
}
|
132
|
+
// Use pick_first if nothing was specified and we didn't select grpclb
|
133
|
+
// above.
|
134
|
+
if (lb_policy_name == nullptr) lb_policy_name = "pick_first";
|
135
|
+
lb_policy_name_.reset(gpr_strdup(lb_policy_name));
|
136
|
+
}
|
137
|
+
|
138
|
+
void ProcessedResolverResult::ParseServiceConfig(
|
139
|
+
const grpc_json* field, ProcessedResolverResult* parsing_state) {
|
140
|
+
parsing_state->ParseLbConfigFromServiceConfig(field);
|
141
|
+
if (parsing_state->server_name_ != nullptr) {
|
142
|
+
parsing_state->ParseRetryThrottleParamsFromServiceConfig(field);
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
void ProcessedResolverResult::ParseLbConfigFromServiceConfig(
|
147
|
+
const grpc_json* field) {
|
148
|
+
if (lb_policy_config_ != nullptr) return; // Already found.
|
149
|
+
// Find the LB config global parameter.
|
150
|
+
if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0 ||
|
151
|
+
field->type != GRPC_JSON_ARRAY) {
|
152
|
+
return; // Not valid lb config array.
|
153
|
+
}
|
154
|
+
// Find the first LB policy that this client supports.
|
155
|
+
for (grpc_json* lb_config = field->child; lb_config != nullptr;
|
156
|
+
lb_config = lb_config->next) {
|
157
|
+
if (lb_config->type != GRPC_JSON_OBJECT) return;
|
158
|
+
// Find the policy object.
|
159
|
+
grpc_json* policy = nullptr;
|
160
|
+
for (grpc_json* field = lb_config->child; field != nullptr;
|
161
|
+
field = field->next) {
|
162
|
+
if (field->key == nullptr || strcmp(field->key, "policy") != 0 ||
|
163
|
+
field->type != GRPC_JSON_OBJECT) {
|
164
|
+
return;
|
165
|
+
}
|
166
|
+
if (policy != nullptr) return; // Duplicate.
|
167
|
+
policy = field;
|
168
|
+
}
|
169
|
+
// Find the specific policy content since the policy object is of type
|
170
|
+
// "oneof".
|
171
|
+
grpc_json* policy_content = nullptr;
|
172
|
+
for (grpc_json* field = policy->child; field != nullptr;
|
173
|
+
field = field->next) {
|
174
|
+
if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) return;
|
175
|
+
if (policy_content != nullptr) return; // Violate "oneof" type.
|
176
|
+
policy_content = field;
|
177
|
+
}
|
178
|
+
grpc_core::UniquePtr<char> lb_policy_name =
|
179
|
+
ConvertCamelToSnake(policy_content->key);
|
180
|
+
if (!grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
|
181
|
+
lb_policy_name.get())) {
|
182
|
+
continue;
|
183
|
+
}
|
184
|
+
lb_policy_name_ = std::move(lb_policy_name);
|
185
|
+
lb_policy_config_ = policy_content->child;
|
186
|
+
return;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
void ProcessedResolverResult::ParseRetryThrottleParamsFromServiceConfig(
|
191
|
+
const grpc_json* field) {
|
192
|
+
if (strcmp(field->key, "retryThrottling") == 0) {
|
193
|
+
if (retry_throttle_data_ != nullptr) return; // Duplicate.
|
194
|
+
if (field->type != GRPC_JSON_OBJECT) return;
|
195
|
+
int max_milli_tokens = 0;
|
196
|
+
int milli_token_ratio = 0;
|
197
|
+
for (grpc_json* sub_field = field->child; sub_field != nullptr;
|
198
|
+
sub_field = sub_field->next) {
|
199
|
+
if (sub_field->key == nullptr) return;
|
200
|
+
if (strcmp(sub_field->key, "maxTokens") == 0) {
|
201
|
+
if (max_milli_tokens != 0) return; // Duplicate.
|
202
|
+
if (sub_field->type != GRPC_JSON_NUMBER) return;
|
203
|
+
max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
|
204
|
+
if (max_milli_tokens == -1) return;
|
205
|
+
max_milli_tokens *= 1000;
|
206
|
+
} else if (strcmp(sub_field->key, "tokenRatio") == 0) {
|
207
|
+
if (milli_token_ratio != 0) return; // Duplicate.
|
208
|
+
if (sub_field->type != GRPC_JSON_NUMBER) return;
|
209
|
+
// We support up to 3 decimal digits.
|
210
|
+
size_t whole_len = strlen(sub_field->value);
|
211
|
+
uint32_t multiplier = 1;
|
212
|
+
uint32_t decimal_value = 0;
|
213
|
+
const char* decimal_point = strchr(sub_field->value, '.');
|
214
|
+
if (decimal_point != nullptr) {
|
215
|
+
whole_len = static_cast<size_t>(decimal_point - sub_field->value);
|
216
|
+
multiplier = 1000;
|
217
|
+
size_t decimal_len = strlen(decimal_point + 1);
|
218
|
+
if (decimal_len > 3) decimal_len = 3;
|
219
|
+
if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
|
220
|
+
&decimal_value)) {
|
221
|
+
return;
|
222
|
+
}
|
223
|
+
uint32_t decimal_multiplier = 1;
|
224
|
+
for (size_t i = 0; i < (3 - decimal_len); ++i) {
|
225
|
+
decimal_multiplier *= 10;
|
226
|
+
}
|
227
|
+
decimal_value *= decimal_multiplier;
|
228
|
+
}
|
229
|
+
uint32_t whole_value;
|
230
|
+
if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
|
231
|
+
&whole_value)) {
|
232
|
+
return;
|
233
|
+
}
|
234
|
+
milli_token_ratio =
|
235
|
+
static_cast<int>((whole_value * multiplier) + decimal_value);
|
236
|
+
if (milli_token_ratio <= 0) return;
|
237
|
+
}
|
238
|
+
}
|
239
|
+
retry_throttle_data_ =
|
240
|
+
grpc_core::internal::ServerRetryThrottleMap::GetDataForServer(
|
241
|
+
server_name_, max_milli_tokens, milli_token_ratio);
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
namespace {
|
246
|
+
|
247
|
+
bool ParseWaitForReady(
|
248
|
+
grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) {
|
249
|
+
if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
|
250
|
+
return false;
|
251
|
+
}
|
252
|
+
*wait_for_ready = field->type == GRPC_JSON_TRUE
|
253
|
+
? ClientChannelMethodParams::WAIT_FOR_READY_TRUE
|
254
|
+
: ClientChannelMethodParams::WAIT_FOR_READY_FALSE;
|
255
|
+
return true;
|
256
|
+
}
|
257
|
+
|
258
|
+
// Parses a JSON field of the form generated for a google.proto.Duration
|
259
|
+
// proto message, as per:
|
260
|
+
// https://developers.google.com/protocol-buffers/docs/proto3#json
|
261
|
+
bool ParseDuration(grpc_json* field, grpc_millis* duration) {
|
262
|
+
if (field->type != GRPC_JSON_STRING) return false;
|
263
|
+
size_t len = strlen(field->value);
|
264
|
+
if (field->value[len - 1] != 's') return false;
|
265
|
+
UniquePtr<char> buf(gpr_strdup(field->value));
|
266
|
+
*(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
|
267
|
+
char* decimal_point = strchr(buf.get(), '.');
|
268
|
+
int nanos = 0;
|
269
|
+
if (decimal_point != nullptr) {
|
270
|
+
*decimal_point = '\0';
|
271
|
+
nanos = gpr_parse_nonnegative_int(decimal_point + 1);
|
272
|
+
if (nanos == -1) {
|
273
|
+
return false;
|
274
|
+
}
|
275
|
+
int num_digits = static_cast<int>(strlen(decimal_point + 1));
|
276
|
+
if (num_digits > 9) { // We don't accept greater precision than nanos.
|
277
|
+
return false;
|
278
|
+
}
|
279
|
+
for (int i = 0; i < (9 - num_digits); ++i) {
|
280
|
+
nanos *= 10;
|
281
|
+
}
|
282
|
+
}
|
283
|
+
int seconds =
|
284
|
+
decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
|
285
|
+
if (seconds == -1) return false;
|
286
|
+
*duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
|
287
|
+
return true;
|
288
|
+
}
|
289
|
+
|
290
|
+
UniquePtr<ClientChannelMethodParams::RetryPolicy> ParseRetryPolicy(
|
291
|
+
grpc_json* field) {
|
292
|
+
auto retry_policy = MakeUnique<ClientChannelMethodParams::RetryPolicy>();
|
293
|
+
if (field->type != GRPC_JSON_OBJECT) return nullptr;
|
294
|
+
for (grpc_json* sub_field = field->child; sub_field != nullptr;
|
295
|
+
sub_field = sub_field->next) {
|
296
|
+
if (sub_field->key == nullptr) return nullptr;
|
297
|
+
if (strcmp(sub_field->key, "maxAttempts") == 0) {
|
298
|
+
if (retry_policy->max_attempts != 0) return nullptr; // Duplicate.
|
299
|
+
if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
|
300
|
+
retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value);
|
301
|
+
if (retry_policy->max_attempts <= 1) return nullptr;
|
302
|
+
if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) {
|
303
|
+
gpr_log(GPR_ERROR,
|
304
|
+
"service config: clamped retryPolicy.maxAttempts at %d",
|
305
|
+
MAX_MAX_RETRY_ATTEMPTS);
|
306
|
+
retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS;
|
307
|
+
}
|
308
|
+
} else if (strcmp(sub_field->key, "initialBackoff") == 0) {
|
309
|
+
if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate.
|
310
|
+
if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) {
|
311
|
+
return nullptr;
|
312
|
+
}
|
313
|
+
if (retry_policy->initial_backoff == 0) return nullptr;
|
314
|
+
} else if (strcmp(sub_field->key, "maxBackoff") == 0) {
|
315
|
+
if (retry_policy->max_backoff > 0) return nullptr; // Duplicate.
|
316
|
+
if (!ParseDuration(sub_field, &retry_policy->max_backoff)) {
|
317
|
+
return nullptr;
|
318
|
+
}
|
319
|
+
if (retry_policy->max_backoff == 0) return nullptr;
|
320
|
+
} else if (strcmp(sub_field->key, "backoffMultiplier") == 0) {
|
321
|
+
if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate.
|
322
|
+
if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
|
323
|
+
if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) !=
|
324
|
+
1) {
|
325
|
+
return nullptr;
|
326
|
+
}
|
327
|
+
if (retry_policy->backoff_multiplier <= 0) return nullptr;
|
328
|
+
} else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) {
|
329
|
+
if (!retry_policy->retryable_status_codes.Empty()) {
|
330
|
+
return nullptr; // Duplicate.
|
331
|
+
}
|
332
|
+
if (sub_field->type != GRPC_JSON_ARRAY) return nullptr;
|
333
|
+
for (grpc_json* element = sub_field->child; element != nullptr;
|
334
|
+
element = element->next) {
|
335
|
+
if (element->type != GRPC_JSON_STRING) return nullptr;
|
336
|
+
grpc_status_code status;
|
337
|
+
if (!grpc_status_code_from_string(element->value, &status)) {
|
338
|
+
return nullptr;
|
339
|
+
}
|
340
|
+
retry_policy->retryable_status_codes.Add(status);
|
341
|
+
}
|
342
|
+
if (retry_policy->retryable_status_codes.Empty()) return nullptr;
|
343
|
+
}
|
344
|
+
}
|
345
|
+
// Make sure required fields are set.
|
346
|
+
if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
|
347
|
+
retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 ||
|
348
|
+
retry_policy->retryable_status_codes.Empty()) {
|
349
|
+
return nullptr;
|
350
|
+
}
|
351
|
+
return retry_policy;
|
352
|
+
}
|
353
|
+
|
354
|
+
} // namespace
|
355
|
+
|
356
|
+
RefCountedPtr<ClientChannelMethodParams>
|
357
|
+
ClientChannelMethodParams::CreateFromJson(const grpc_json* json) {
|
358
|
+
RefCountedPtr<ClientChannelMethodParams> method_params =
|
359
|
+
MakeRefCounted<ClientChannelMethodParams>();
|
360
|
+
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
|
361
|
+
if (field->key == nullptr) continue;
|
362
|
+
if (strcmp(field->key, "waitForReady") == 0) {
|
363
|
+
if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) {
|
364
|
+
return nullptr; // Duplicate.
|
365
|
+
}
|
366
|
+
if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) {
|
367
|
+
return nullptr;
|
368
|
+
}
|
369
|
+
} else if (strcmp(field->key, "timeout") == 0) {
|
370
|
+
if (method_params->timeout_ > 0) return nullptr; // Duplicate.
|
371
|
+
if (!ParseDuration(field, &method_params->timeout_)) return nullptr;
|
372
|
+
} else if (strcmp(field->key, "retryPolicy") == 0) {
|
373
|
+
if (method_params->retry_policy_ != nullptr) {
|
374
|
+
return nullptr; // Duplicate.
|
375
|
+
}
|
376
|
+
method_params->retry_policy_ = ParseRetryPolicy(field);
|
377
|
+
if (method_params->retry_policy_ == nullptr) return nullptr;
|
378
|
+
}
|
379
|
+
}
|
380
|
+
return method_params;
|
381
|
+
}
|
382
|
+
|
383
|
+
} // namespace internal
|
384
|
+
} // namespace grpc_core
|
@@ -0,0 +1,146 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2018 gRPC authors.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*
|
17
|
+
*/
|
18
|
+
|
19
|
+
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H
|
20
|
+
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H
|
21
|
+
|
22
|
+
#include <grpc/support/port_platform.h>
|
23
|
+
|
24
|
+
#include "src/core/ext/filters/client_channel/retry_throttle.h"
|
25
|
+
#include "src/core/lib/channel/status_util.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/exec_ctx.h" // for grpc_millis
|
29
|
+
#include "src/core/lib/json/json.h"
|
30
|
+
#include "src/core/lib/slice/slice_hash_table.h"
|
31
|
+
#include "src/core/lib/transport/service_config.h"
|
32
|
+
|
33
|
+
namespace grpc_core {
|
34
|
+
namespace internal {
|
35
|
+
|
36
|
+
class ClientChannelMethodParams;
|
37
|
+
|
38
|
+
// A table mapping from a method name to its method parameters.
|
39
|
+
typedef grpc_core::SliceHashTable<
|
40
|
+
grpc_core::RefCountedPtr<ClientChannelMethodParams>>
|
41
|
+
ClientChannelMethodParamsTable;
|
42
|
+
|
43
|
+
// A container of processed fields from the resolver result. Simplifies the
|
44
|
+
// usage of resolver result.
|
45
|
+
class ProcessedResolverResult {
|
46
|
+
public:
|
47
|
+
// Processes the resolver result and populates the relative members
|
48
|
+
// for later consumption. Tries to parse retry parameters only if parse_retry
|
49
|
+
// is true.
|
50
|
+
ProcessedResolverResult(const grpc_channel_args* resolver_result,
|
51
|
+
bool parse_retry);
|
52
|
+
|
53
|
+
// Getters. Any managed object's ownership is transferred.
|
54
|
+
grpc_core::UniquePtr<char> service_config_json() {
|
55
|
+
return std::move(service_config_json_);
|
56
|
+
}
|
57
|
+
grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data() {
|
58
|
+
return std::move(retry_throttle_data_);
|
59
|
+
}
|
60
|
+
grpc_core::RefCountedPtr<ClientChannelMethodParamsTable>
|
61
|
+
method_params_table() {
|
62
|
+
return std::move(method_params_table_);
|
63
|
+
}
|
64
|
+
grpc_core::UniquePtr<char> lb_policy_name() {
|
65
|
+
return std::move(lb_policy_name_);
|
66
|
+
}
|
67
|
+
grpc_json* lb_policy_config() { return lb_policy_config_; }
|
68
|
+
|
69
|
+
private:
|
70
|
+
// Finds the service config; extracts LB config and (maybe) retry throttle
|
71
|
+
// params from it.
|
72
|
+
void ProcessServiceConfig(const grpc_channel_args* resolver_result,
|
73
|
+
bool parse_retry);
|
74
|
+
|
75
|
+
// Finds the LB policy name (when no LB config was found).
|
76
|
+
void ProcessLbPolicyName(const grpc_channel_args* resolver_result);
|
77
|
+
|
78
|
+
// Parses the service config. Intended to be used by
|
79
|
+
// ServiceConfig::ParseGlobalParams.
|
80
|
+
static void ParseServiceConfig(const grpc_json* field,
|
81
|
+
ProcessedResolverResult* parsing_state);
|
82
|
+
// Parses the LB config from service config.
|
83
|
+
void ParseLbConfigFromServiceConfig(const grpc_json* field);
|
84
|
+
// Parses the retry throttle parameters from service config.
|
85
|
+
void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field);
|
86
|
+
|
87
|
+
// Service config.
|
88
|
+
grpc_core::UniquePtr<char> service_config_json_;
|
89
|
+
grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config_;
|
90
|
+
// LB policy.
|
91
|
+
grpc_json* lb_policy_config_ = nullptr;
|
92
|
+
grpc_core::UniquePtr<char> lb_policy_name_;
|
93
|
+
// Retry throttle data.
|
94
|
+
char* server_name_ = nullptr;
|
95
|
+
grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
|
96
|
+
// Method params table.
|
97
|
+
grpc_core::RefCountedPtr<ClientChannelMethodParamsTable> method_params_table_;
|
98
|
+
};
|
99
|
+
|
100
|
+
// The parameters of a method.
|
101
|
+
class ClientChannelMethodParams : public RefCounted<ClientChannelMethodParams> {
|
102
|
+
public:
|
103
|
+
enum WaitForReady {
|
104
|
+
WAIT_FOR_READY_UNSET = 0,
|
105
|
+
WAIT_FOR_READY_FALSE,
|
106
|
+
WAIT_FOR_READY_TRUE
|
107
|
+
};
|
108
|
+
|
109
|
+
struct RetryPolicy {
|
110
|
+
int max_attempts = 0;
|
111
|
+
grpc_millis initial_backoff = 0;
|
112
|
+
grpc_millis max_backoff = 0;
|
113
|
+
float backoff_multiplier = 0;
|
114
|
+
StatusCodeSet retryable_status_codes;
|
115
|
+
};
|
116
|
+
|
117
|
+
/// Creates a method_parameters object from \a json.
|
118
|
+
/// Intended for use with ServiceConfig::CreateMethodConfigTable().
|
119
|
+
static RefCountedPtr<ClientChannelMethodParams> CreateFromJson(
|
120
|
+
const grpc_json* json);
|
121
|
+
|
122
|
+
grpc_millis timeout() const { return timeout_; }
|
123
|
+
WaitForReady wait_for_ready() const { return wait_for_ready_; }
|
124
|
+
const RetryPolicy* retry_policy() const { return retry_policy_.get(); }
|
125
|
+
|
126
|
+
private:
|
127
|
+
// So New() can call our private ctor.
|
128
|
+
template <typename T, typename... Args>
|
129
|
+
friend T* grpc_core::New(Args&&... args);
|
130
|
+
|
131
|
+
// So Delete() can call our private dtor.
|
132
|
+
template <typename T>
|
133
|
+
friend void grpc_core::Delete(T*);
|
134
|
+
|
135
|
+
ClientChannelMethodParams() {}
|
136
|
+
virtual ~ClientChannelMethodParams() {}
|
137
|
+
|
138
|
+
grpc_millis timeout_ = 0;
|
139
|
+
WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET;
|
140
|
+
UniquePtr<RetryPolicy> retry_policy_;
|
141
|
+
};
|
142
|
+
|
143
|
+
} // namespace internal
|
144
|
+
} // namespace grpc_core
|
145
|
+
|
146
|
+
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H */
|