grpc 1.23.1 → 1.24.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.

Files changed (245) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +757 -477
  3. data/include/grpc/grpc.h +3 -1
  4. data/include/grpc/grpc_security.h +20 -4
  5. data/include/grpc/impl/codegen/grpc_types.h +6 -5
  6. data/include/grpc/impl/codegen/port_platform.h +25 -0
  7. data/src/core/ext/filters/client_channel/backend_metric.cc +78 -0
  8. data/src/core/ext/filters/client_channel/backend_metric.h +36 -0
  9. data/src/core/ext/filters/client_channel/channel_connectivity.cc +16 -2
  10. data/src/core/ext/filters/client_channel/client_channel.cc +325 -267
  11. data/src/core/ext/filters/client_channel/client_channel_factory.h +0 -4
  12. data/src/core/ext/filters/client_channel/health/health_check_client.cc +23 -32
  13. data/src/core/ext/filters/client_channel/http_proxy.cc +7 -3
  14. data/src/core/ext/filters/client_channel/lb_policy.cc +1 -1
  15. data/src/core/ext/filters/client_channel/lb_policy.h +58 -34
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +46 -50
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +9 -2
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +35 -17
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +130 -215
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +34 -21
  21. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +1120 -802
  22. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +8 -2
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +33 -12
  24. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc +151 -40
  25. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h +184 -26
  26. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +389 -245
  27. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +98 -60
  28. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +6 -1
  29. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +89 -0
  30. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +3 -8
  31. data/src/core/ext/filters/client_channel/server_address.cc +1 -3
  32. data/src/core/ext/filters/client_channel/server_address.h +1 -1
  33. data/src/core/ext/filters/client_channel/subchannel.h +2 -1
  34. data/src/core/ext/filters/client_idle/client_idle_filter.cc +207 -29
  35. data/src/core/ext/filters/http/client/http_client_filter.cc +10 -8
  36. data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
  37. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +10 -7
  38. data/src/core/ext/filters/http/server/http_server_filter.cc +52 -26
  39. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +23 -20
  40. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +24 -21
  41. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +1 -1
  42. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +37 -24
  43. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +1 -0
  44. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +237 -191
  45. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +29 -27
  46. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +1 -1
  47. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +19 -4
  48. data/src/core/ext/transport/chttp2/transport/hpack_table.h +13 -4
  49. data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +2 -1
  50. data/src/core/ext/transport/chttp2/transport/internal.h +0 -2
  51. data/src/core/ext/transport/chttp2/transport/parsing.cc +99 -71
  52. data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c +222 -0
  53. data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h +818 -0
  54. data/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c +314 -0
  55. data/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h +1142 -0
  56. data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c +53 -0
  57. data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h +158 -0
  58. data/src/core/ext/upb-generated/envoy/api/v2/cluster/filter.upb.c +34 -0
  59. data/src/core/ext/upb-generated/envoy/api/v2/cluster/filter.upb.h +69 -0
  60. data/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c +49 -0
  61. data/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h +240 -0
  62. data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c +110 -0
  63. data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h +324 -0
  64. data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c +235 -0
  65. data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h +661 -0
  66. data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c +84 -0
  67. data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h +274 -0
  68. data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c +175 -0
  69. data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h +572 -0
  70. data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c +150 -0
  71. data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h +596 -0
  72. data/src/core/ext/upb-generated/envoy/api/v2/core/http_uri.upb.c +35 -0
  73. data/src/core/ext/upb-generated/envoy/api/v2/core/http_uri.upb.h +80 -0
  74. data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c +95 -0
  75. data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h +308 -0
  76. data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c +128 -0
  77. data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h +392 -0
  78. data/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c +91 -0
  79. data/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h +236 -0
  80. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c +88 -0
  81. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h +258 -0
  82. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c +111 -0
  83. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h +324 -0
  84. data/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c +23 -0
  85. data/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h +50 -0
  86. data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c +52 -0
  87. data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h +130 -0
  88. data/src/core/ext/upb-generated/envoy/type/percent.upb.c +39 -0
  89. data/src/core/ext/upb-generated/envoy/type/percent.upb.h +87 -0
  90. data/src/core/ext/upb-generated/envoy/type/range.upb.c +39 -0
  91. data/src/core/ext/upb-generated/envoy/type/range.upb.h +85 -0
  92. data/src/core/ext/upb-generated/gogoproto/gogo.upb.c +17 -0
  93. data/src/core/ext/upb-generated/gogoproto/gogo.upb.h +30 -0
  94. data/src/core/ext/upb-generated/google/api/annotations.upb.c +18 -0
  95. data/src/core/ext/upb-generated/google/api/annotations.upb.h +30 -0
  96. data/src/core/ext/upb-generated/google/api/http.upb.c +66 -0
  97. data/src/core/ext/upb-generated/google/api/http.upb.h +190 -0
  98. data/src/core/ext/upb-generated/google/protobuf/any.upb.c +27 -0
  99. data/src/core/ext/upb-generated/google/protobuf/any.upb.h +58 -0
  100. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +485 -0
  101. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +1690 -0
  102. data/src/core/ext/upb-generated/google/protobuf/duration.upb.c +27 -0
  103. data/src/core/ext/upb-generated/google/protobuf/duration.upb.h +58 -0
  104. data/src/core/ext/upb-generated/google/protobuf/empty.upb.c +22 -0
  105. data/src/core/ext/upb-generated/google/protobuf/empty.upb.h +50 -0
  106. data/src/core/ext/upb-generated/google/protobuf/struct.upb.c +79 -0
  107. data/src/core/ext/upb-generated/google/protobuf/struct.upb.h +215 -0
  108. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c +27 -0
  109. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +58 -0
  110. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c +106 -0
  111. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +238 -0
  112. data/src/core/ext/upb-generated/google/rpc/status.upb.c +33 -0
  113. data/src/core/ext/upb-generated/google/rpc/status.upb.h +74 -0
  114. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c +49 -0
  115. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h +126 -0
  116. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c +209 -0
  117. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h +681 -0
  118. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c +42 -0
  119. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h +109 -0
  120. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c +36 -0
  121. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h +84 -0
  122. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c +133 -0
  123. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h +359 -0
  124. data/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c +58 -0
  125. data/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h +144 -0
  126. data/src/core/ext/upb-generated/validate/validate.upb.c +443 -0
  127. data/src/core/ext/upb-generated/validate/validate.upb.h +2037 -0
  128. data/src/core/lib/channel/channel_args.cc +21 -0
  129. data/src/core/lib/channel/channel_args.h +16 -2
  130. data/src/core/lib/channel/channel_stack.h +2 -1
  131. data/src/core/lib/channel/channelz.cc +54 -56
  132. data/src/core/lib/channel/channelz.h +29 -12
  133. data/src/core/lib/compression/compression.cc +2 -1
  134. data/src/core/lib/compression/compression_internal.h +8 -0
  135. data/src/core/lib/gpr/log_linux.cc +2 -2
  136. data/src/core/lib/gpr/log_posix.cc +2 -2
  137. data/src/core/lib/gpr/time_precise.cc +123 -36
  138. data/src/core/lib/gpr/time_precise.h +37 -0
  139. data/src/core/lib/gprpp/abstract.h +10 -0
  140. data/src/core/lib/gprpp/atomic.h +4 -0
  141. data/src/core/lib/gprpp/inlined_vector.h +20 -4
  142. data/src/core/lib/gprpp/map.h +109 -6
  143. data/src/core/lib/gprpp/memory.h +6 -0
  144. data/src/core/lib/gprpp/ref_counted_ptr.h +2 -0
  145. data/src/core/lib/iomgr/ev_epollex_linux.cc +29 -54
  146. data/src/core/lib/iomgr/exec_ctx.cc +27 -17
  147. data/src/core/lib/iomgr/exec_ctx.h +3 -0
  148. data/src/core/lib/iomgr/sockaddr_utils.cc +1 -3
  149. data/src/core/lib/iomgr/tcp_posix.cc +16 -25
  150. data/src/core/lib/iomgr/tcp_server_custom.cc +1 -1
  151. data/src/core/lib/iomgr/timer_manager.cc +8 -1
  152. data/src/core/lib/iomgr/timer_manager.h +2 -0
  153. data/src/core/lib/security/credentials/credentials.h +8 -2
  154. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +23 -0
  155. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +3 -0
  156. data/src/core/lib/security/credentials/tls/spiffe_credentials.cc +3 -3
  157. data/src/core/lib/security/security_connector/ssl_utils.cc +1 -12
  158. data/src/core/lib/security/security_connector/ssl_utils.h +10 -6
  159. data/src/core/lib/security/security_connector/ssl_utils_config.cc +32 -0
  160. data/src/core/lib/security/security_connector/ssl_utils_config.h +30 -0
  161. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +161 -49
  162. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +34 -1
  163. data/src/core/lib/slice/slice_intern.cc +17 -9
  164. data/src/core/lib/slice/slice_internal.h +34 -7
  165. data/src/core/lib/slice/slice_utils.h +7 -3
  166. data/src/core/lib/surface/call.cc +97 -57
  167. data/src/core/lib/surface/channel.cc +2 -2
  168. data/src/core/lib/surface/completion_queue.cc +10 -16
  169. data/src/core/lib/surface/init.cc +3 -0
  170. data/src/core/lib/surface/server.cc +11 -14
  171. data/src/core/lib/surface/validate_metadata.cc +4 -0
  172. data/src/core/lib/surface/version.cc +2 -2
  173. data/src/core/lib/transport/metadata.cc +4 -4
  174. data/src/core/lib/transport/metadata_batch.cc +72 -16
  175. data/src/core/lib/transport/metadata_batch.h +38 -0
  176. data/src/core/lib/transport/static_metadata.cc +814 -1023
  177. data/src/core/lib/transport/static_metadata.h +271 -213
  178. data/src/core/lib/transport/transport.h +12 -0
  179. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  180. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +104 -76
  181. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +34 -16
  182. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +2 -2
  183. data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +10 -6
  184. data/src/core/tsi/alts/handshaker/alts_tsi_utils.h +4 -3
  185. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +74 -48
  186. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +34 -26
  187. data/src/core/tsi/ssl_transport_security.cc +14 -6
  188. data/src/core/tsi/ssl_transport_security.h +4 -0
  189. data/src/ruby/ext/grpc/ext-export.clang +1 -0
  190. data/src/ruby/ext/grpc/ext-export.gcc +6 -0
  191. data/src/ruby/ext/grpc/extconf.rb +5 -0
  192. data/src/ruby/ext/grpc/rb_enable_cpp.cc +22 -0
  193. data/src/ruby/ext/grpc/rb_grpc.c +1 -42
  194. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  195. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  196. data/src/ruby/lib/grpc.rb +2 -0
  197. data/src/ruby/lib/grpc/core/status_codes.rb +135 -0
  198. data/src/ruby/lib/grpc/errors.rb +4 -7
  199. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +9 -4
  200. data/src/ruby/lib/grpc/structs.rb +15 -0
  201. data/src/ruby/lib/grpc/version.rb +1 -1
  202. data/src/ruby/spec/errors_spec.rb +1 -0
  203. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import.proto +22 -0
  204. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_ruby_style.proto +34 -0
  205. data/src/ruby/spec/pb/codegen/package_option_spec.rb +53 -29
  206. data/third_party/upb/upb/decode.c +604 -0
  207. data/third_party/upb/upb/decode.h +21 -0
  208. data/third_party/upb/upb/encode.c +378 -0
  209. data/third_party/upb/upb/encode.h +21 -0
  210. data/third_party/upb/upb/generated_util.h +105 -0
  211. data/third_party/upb/upb/msg.c +111 -0
  212. data/third_party/upb/upb/msg.h +69 -0
  213. data/third_party/upb/upb/port.c +27 -0
  214. data/third_party/upb/upb/port_def.inc +152 -0
  215. data/third_party/upb/upb/port_undef.inc +21 -0
  216. data/third_party/upb/upb/table.c +911 -0
  217. data/third_party/upb/upb/table.int.h +507 -0
  218. data/third_party/upb/upb/upb.c +261 -0
  219. data/third_party/upb/upb/upb.h +364 -0
  220. metadata +134 -55
  221. data/src/core/ext/filters/client_channel/health/health.pb.c +0 -23
  222. data/src/core/ext/filters/client_channel/health/health.pb.h +0 -73
  223. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c +0 -19
  224. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h +0 -54
  225. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c +0 -19
  226. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h +0 -54
  227. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +0 -89
  228. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +0 -164
  229. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc +0 -520
  230. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api.h +0 -323
  231. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc +0 -145
  232. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h +0 -149
  233. data/src/core/tsi/alts/handshaker/altscontext.pb.c +0 -47
  234. data/src/core/tsi/alts/handshaker/altscontext.pb.h +0 -63
  235. data/src/core/tsi/alts/handshaker/handshaker.pb.c +0 -122
  236. data/src/core/tsi/alts/handshaker/handshaker.pb.h +0 -254
  237. data/src/core/tsi/alts/handshaker/transport_security_common.pb.c +0 -49
  238. data/src/core/tsi/alts/handshaker/transport_security_common.pb.h +0 -78
  239. data/third_party/nanopb/pb.h +0 -579
  240. data/third_party/nanopb/pb_common.c +0 -97
  241. data/third_party/nanopb/pb_common.h +0 -42
  242. data/third_party/nanopb/pb_decode.c +0 -1347
  243. data/third_party/nanopb/pb_decode.h +0 -149
  244. data/third_party/nanopb/pb_encode.c +0 -696
  245. data/third_party/nanopb/pb_encode.h +0 -154
@@ -18,294 +18,438 @@
18
18
 
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
- #include "pb_decode.h"
22
- #include "pb_encode.h"
23
- #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h"
21
+ #include <algorithm>
24
22
 
23
+ #include <grpc/impl/codegen/log.h>
25
24
  #include <grpc/support/alloc.h>
25
+ #include <grpc/support/string_util.h>
26
26
 
27
- /* invoked once for every Server in ServerList */
28
- static bool count_serverlist(pb_istream_t* stream, const pb_field_t* field,
29
- void** arg) {
30
- xds_grpclb_serverlist* sl = static_cast<xds_grpclb_serverlist*>(*arg);
31
- xds_grpclb_server server;
32
- if (GPR_UNLIKELY(!pb_decode(stream, grpc_lb_v1_Server_fields, &server))) {
33
- gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(stream));
34
- return false;
35
- }
36
- ++sl->num_servers;
37
- return true;
38
- }
27
+ #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h"
28
+ #include "src/core/lib/iomgr/error.h"
29
+ #include "src/core/lib/iomgr/sockaddr_utils.h"
39
30
 
40
- typedef struct decode_serverlist_arg {
41
- /* The decoding callback is invoked once per server in serverlist. Remember
42
- * which index of the serverlist are we currently decoding */
43
- size_t decoding_idx;
44
- /* The decoded serverlist */
45
- xds_grpclb_serverlist* serverlist;
46
- } decode_serverlist_arg;
31
+ #include "envoy/api/v2/core/address.upb.h"
32
+ #include "envoy/api/v2/core/base.upb.h"
33
+ #include "envoy/api/v2/discovery.upb.h"
34
+ #include "envoy/api/v2/eds.upb.h"
35
+ #include "envoy/api/v2/endpoint/endpoint.upb.h"
36
+ #include "envoy/api/v2/endpoint/load_report.upb.h"
37
+ #include "envoy/service/load_stats/v2/lrs.upb.h"
38
+ #include "envoy/type/percent.upb.h"
39
+ #include "google/protobuf/any.upb.h"
40
+ #include "google/protobuf/duration.upb.h"
41
+ #include "google/protobuf/struct.upb.h"
42
+ #include "google/protobuf/timestamp.upb.h"
43
+ #include "google/protobuf/wrappers.upb.h"
44
+ #include "upb/upb.h"
47
45
 
48
- /* invoked once for every Server in ServerList */
49
- static bool decode_serverlist(pb_istream_t* stream, const pb_field_t* field,
50
- void** arg) {
51
- decode_serverlist_arg* dec_arg = static_cast<decode_serverlist_arg*>(*arg);
52
- GPR_ASSERT(dec_arg->serverlist->num_servers >= dec_arg->decoding_idx);
53
- xds_grpclb_server* server =
54
- static_cast<xds_grpclb_server*>(gpr_zalloc(sizeof(xds_grpclb_server)));
55
- if (GPR_UNLIKELY(!pb_decode(stream, grpc_lb_v1_Server_fields, server))) {
56
- gpr_free(server);
57
- gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(stream));
58
- return false;
59
- }
60
- dec_arg->serverlist->servers[dec_arg->decoding_idx++] = server;
61
- return true;
62
- }
46
+ namespace grpc_core {
63
47
 
64
- xds_grpclb_request* xds_grpclb_request_create(const char* lb_service_name) {
65
- xds_grpclb_request* req =
66
- static_cast<xds_grpclb_request*>(gpr_malloc(sizeof(xds_grpclb_request)));
67
- req->has_client_stats = false;
68
- req->has_initial_request = true;
69
- req->initial_request.has_name = true;
70
- // GCC warns (-Wstringop-truncation) because the destination
71
- // buffer size is identical to max-size, leading to a potential
72
- // char[] with no null terminator. nanopb can handle it fine,
73
- // and parantheses around strncpy silence that compiler warning.
74
- (strncpy(req->initial_request.name, lb_service_name,
75
- XDS_SERVICE_NAME_MAX_LENGTH));
76
- return req;
77
- }
48
+ namespace {
78
49
 
79
- static void populate_timestamp(gpr_timespec timestamp,
80
- xds_grpclb_timestamp* timestamp_pb) {
81
- timestamp_pb->has_seconds = true;
82
- timestamp_pb->seconds = timestamp.tv_sec;
83
- timestamp_pb->has_nanos = true;
84
- timestamp_pb->nanos = timestamp.tv_nsec;
85
- }
50
+ constexpr char kEdsTypeUrl[] =
51
+ "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment";
52
+ constexpr char kEndpointRequired[] = "endpointRequired";
86
53
 
87
- static bool encode_string(pb_ostream_t* stream, const pb_field_t* field,
88
- void* const* arg) {
89
- char* str = static_cast<char*>(*arg);
90
- if (!pb_encode_tag_for_field(stream, field)) return false;
91
- return pb_encode_string(stream, reinterpret_cast<uint8_t*>(str), strlen(str));
92
- }
54
+ } // namespace
93
55
 
94
- static bool encode_drops(pb_ostream_t* stream, const pb_field_t* field,
95
- void* const* arg) {
96
- grpc_core::XdsLbClientStats::DroppedCallCounts* drop_entries =
97
- static_cast<grpc_core::XdsLbClientStats::DroppedCallCounts*>(*arg);
98
- if (drop_entries == nullptr) return true;
99
- for (size_t i = 0; i < drop_entries->size(); ++i) {
100
- if (!pb_encode_tag_for_field(stream, field)) return false;
101
- grpc_lb_v1_ClientStatsPerToken drop_message;
102
- drop_message.load_balance_token.funcs.encode = encode_string;
103
- drop_message.load_balance_token.arg = (*drop_entries)[i].token.get();
104
- drop_message.has_num_calls = true;
105
- drop_message.num_calls = (*drop_entries)[i].count;
106
- if (!pb_encode_submessage(stream, grpc_lb_v1_ClientStatsPerToken_fields,
107
- &drop_message)) {
108
- return false;
56
+ bool XdsDropConfig::ShouldDrop(const UniquePtr<char>** category_name) const {
57
+ for (size_t i = 0; i < drop_category_list_.size(); ++i) {
58
+ const auto& drop_category = drop_category_list_[i];
59
+ // Generate a random number in [0, 1000000).
60
+ const int random = rand() % 1000000;
61
+ if (random < drop_category.parts_per_million) {
62
+ *category_name = &drop_category.name;
63
+ return true;
109
64
  }
110
65
  }
111
- return true;
66
+ return false;
112
67
  }
113
68
 
114
- xds_grpclb_request* xds_grpclb_load_report_request_create_locked(
115
- grpc_core::XdsLbClientStats* client_stats) {
116
- xds_grpclb_request* req =
117
- static_cast<xds_grpclb_request*>(gpr_zalloc(sizeof(xds_grpclb_request)));
118
- req->has_client_stats = true;
119
- req->client_stats.has_timestamp = true;
120
- populate_timestamp(gpr_now(GPR_CLOCK_REALTIME), &req->client_stats.timestamp);
121
- req->client_stats.has_num_calls_started = true;
122
- req->client_stats.has_num_calls_finished = true;
123
- req->client_stats.has_num_calls_finished_with_client_failed_to_send = true;
124
- req->client_stats.has_num_calls_finished_with_client_failed_to_send = true;
125
- req->client_stats.has_num_calls_finished_known_received = true;
126
- req->client_stats.calls_finished_with_drop.funcs.encode = encode_drops;
127
- grpc_core::UniquePtr<grpc_core::XdsLbClientStats::DroppedCallCounts>
128
- drop_counts;
129
- client_stats->GetLocked(
130
- &req->client_stats.num_calls_started,
131
- &req->client_stats.num_calls_finished,
132
- &req->client_stats.num_calls_finished_with_client_failed_to_send,
133
- &req->client_stats.num_calls_finished_known_received, &drop_counts);
134
- // Will be deleted in xds_grpclb_request_destroy().
135
- req->client_stats.calls_finished_with_drop.arg = drop_counts.release();
136
- return req;
69
+ grpc_slice XdsEdsRequestCreateAndEncode(const char* service_name) {
70
+ upb::Arena arena;
71
+ // Create a request.
72
+ envoy_api_v2_DiscoveryRequest* request =
73
+ envoy_api_v2_DiscoveryRequest_new(arena.ptr());
74
+ envoy_api_v2_core_Node* node =
75
+ envoy_api_v2_DiscoveryRequest_mutable_node(request, arena.ptr());
76
+ google_protobuf_Struct* metadata =
77
+ envoy_api_v2_core_Node_mutable_metadata(node, arena.ptr());
78
+ google_protobuf_Struct_FieldsEntry* field =
79
+ google_protobuf_Struct_add_fields(metadata, arena.ptr());
80
+ google_protobuf_Struct_FieldsEntry_set_key(
81
+ field, upb_strview_makez(kEndpointRequired));
82
+ google_protobuf_Value* value =
83
+ google_protobuf_Struct_FieldsEntry_mutable_value(field, arena.ptr());
84
+ google_protobuf_Value_set_bool_value(value, true);
85
+ envoy_api_v2_DiscoveryRequest_add_resource_names(
86
+ request, upb_strview_makez(service_name), arena.ptr());
87
+ envoy_api_v2_DiscoveryRequest_set_type_url(request,
88
+ upb_strview_makez(kEdsTypeUrl));
89
+ // Encode the request.
90
+ size_t output_length;
91
+ char* output = envoy_api_v2_DiscoveryRequest_serialize(request, arena.ptr(),
92
+ &output_length);
93
+ return grpc_slice_from_copied_buffer(output, output_length);
137
94
  }
138
95
 
139
- grpc_slice xds_grpclb_request_encode(const xds_grpclb_request* request) {
140
- size_t encoded_length;
141
- pb_ostream_t sizestream;
142
- pb_ostream_t outputstream;
143
- grpc_slice slice;
144
- memset(&sizestream, 0, sizeof(pb_ostream_t));
145
- pb_encode(&sizestream, grpc_lb_v1_LoadBalanceRequest_fields, request);
146
- encoded_length = sizestream.bytes_written;
96
+ namespace {
147
97
 
148
- slice = GRPC_SLICE_MALLOC(encoded_length);
149
- outputstream =
150
- pb_ostream_from_buffer(GRPC_SLICE_START_PTR(slice), encoded_length);
151
- GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v1_LoadBalanceRequest_fields,
152
- request) != 0);
153
- return slice;
154
- }
155
-
156
- void xds_grpclb_request_destroy(xds_grpclb_request* request) {
157
- if (request->has_client_stats) {
158
- grpc_core::XdsLbClientStats::DroppedCallCounts* drop_entries =
159
- static_cast<grpc_core::XdsLbClientStats::DroppedCallCounts*>(
160
- request->client_stats.calls_finished_with_drop.arg);
161
- grpc_core::Delete(drop_entries);
98
+ grpc_error* ServerAddressParseAndAppend(
99
+ const envoy_api_v2_endpoint_LbEndpoint* lb_endpoint,
100
+ ServerAddressList* list) {
101
+ // Find the ip:port.
102
+ const envoy_api_v2_endpoint_Endpoint* endpoint =
103
+ envoy_api_v2_endpoint_LbEndpoint_endpoint(lb_endpoint);
104
+ const envoy_api_v2_core_Address* address =
105
+ envoy_api_v2_endpoint_Endpoint_address(endpoint);
106
+ const envoy_api_v2_core_SocketAddress* socket_address =
107
+ envoy_api_v2_core_Address_socket_address(address);
108
+ upb_strview address_strview =
109
+ envoy_api_v2_core_SocketAddress_address(socket_address);
110
+ uint32_t port = envoy_api_v2_core_SocketAddress_port_value(socket_address);
111
+ if (GPR_UNLIKELY(port >> 16) != 0) {
112
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Invalid port.");
162
113
  }
163
- gpr_free(request);
114
+ // Populate grpc_resolved_address.
115
+ grpc_resolved_address addr;
116
+ char* address_str = static_cast<char*>(gpr_malloc(address_strview.size + 1));
117
+ memcpy(address_str, address_strview.data, address_strview.size);
118
+ address_str[address_strview.size] = '\0';
119
+ grpc_string_to_sockaddr(&addr, address_str, port);
120
+ gpr_free(address_str);
121
+ // Append the address to the list.
122
+ list->emplace_back(addr, nullptr);
123
+ return GRPC_ERROR_NONE;
164
124
  }
165
125
 
166
- typedef grpc_lb_v1_LoadBalanceResponse xds_grpclb_response;
167
- xds_grpclb_initial_response* xds_grpclb_initial_response_parse(
168
- const grpc_slice& encoded_xds_grpclb_response) {
169
- pb_istream_t stream = pb_istream_from_buffer(
170
- const_cast<uint8_t*>(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response)),
171
- GRPC_SLICE_LENGTH(encoded_xds_grpclb_response));
172
- xds_grpclb_response res;
173
- memset(&res, 0, sizeof(xds_grpclb_response));
174
- if (GPR_UNLIKELY(
175
- !pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res))) {
176
- gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
177
- return nullptr;
178
- }
126
+ namespace {
179
127
 
180
- if (!res.has_initial_response) return nullptr;
128
+ UniquePtr<char> StringCopy(const upb_strview& strview) {
129
+ char* str = static_cast<char*>(gpr_malloc(strview.size + 1));
130
+ memcpy(str, strview.data, strview.size);
131
+ str[strview.size] = '\0';
132
+ return UniquePtr<char>(str);
133
+ }
181
134
 
182
- xds_grpclb_initial_response* initial_res =
183
- static_cast<xds_grpclb_initial_response*>(
184
- gpr_malloc(sizeof(xds_grpclb_initial_response)));
185
- memcpy(initial_res, &res.initial_response,
186
- sizeof(xds_grpclb_initial_response));
135
+ } // namespace
187
136
 
188
- return initial_res;
137
+ grpc_error* LocalityParse(
138
+ const envoy_api_v2_endpoint_LocalityLbEndpoints* locality_lb_endpoints,
139
+ XdsLocalityInfo* locality_info) {
140
+ // Parse LB weight.
141
+ const google_protobuf_UInt32Value* lb_weight =
142
+ envoy_api_v2_endpoint_LocalityLbEndpoints_load_balancing_weight(
143
+ locality_lb_endpoints);
144
+ // If LB weight is not specified, it means this locality is assigned no load.
145
+ // TODO(juanlishen): When we support CDS to configure the inter-locality
146
+ // policy, we should change the LB weight handling.
147
+ locality_info->lb_weight =
148
+ lb_weight != nullptr ? google_protobuf_UInt32Value_value(lb_weight) : 0;
149
+ if (locality_info->lb_weight == 0) return GRPC_ERROR_NONE;
150
+ // Parse locality name.
151
+ const envoy_api_v2_core_Locality* locality =
152
+ envoy_api_v2_endpoint_LocalityLbEndpoints_locality(locality_lb_endpoints);
153
+ locality_info->locality_name = MakeRefCounted<XdsLocalityName>(
154
+ StringCopy(envoy_api_v2_core_Locality_region(locality)),
155
+ StringCopy(envoy_api_v2_core_Locality_zone(locality)),
156
+ StringCopy(envoy_api_v2_core_Locality_sub_zone(locality)));
157
+ // Parse the addresses.
158
+ size_t size;
159
+ const envoy_api_v2_endpoint_LbEndpoint* const* lb_endpoints =
160
+ envoy_api_v2_endpoint_LocalityLbEndpoints_lb_endpoints(
161
+ locality_lb_endpoints, &size);
162
+ for (size_t i = 0; i < size; ++i) {
163
+ grpc_error* error = ServerAddressParseAndAppend(lb_endpoints[i],
164
+ &locality_info->serverlist);
165
+ if (error != GRPC_ERROR_NONE) return error;
166
+ }
167
+ // Parse the priority.
168
+ locality_info->priority =
169
+ envoy_api_v2_endpoint_LocalityLbEndpoints_priority(locality_lb_endpoints);
170
+ return GRPC_ERROR_NONE;
189
171
  }
190
172
 
191
- xds_grpclb_serverlist* xds_grpclb_response_parse_serverlist(
192
- const grpc_slice& encoded_xds_grpclb_response) {
193
- pb_istream_t stream = pb_istream_from_buffer(
194
- const_cast<uint8_t*>(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response)),
195
- GRPC_SLICE_LENGTH(encoded_xds_grpclb_response));
196
- pb_istream_t stream_at_start = stream;
197
- xds_grpclb_serverlist* sl = static_cast<xds_grpclb_serverlist*>(
198
- gpr_zalloc(sizeof(xds_grpclb_serverlist)));
199
- xds_grpclb_response res;
200
- memset(&res, 0, sizeof(xds_grpclb_response));
201
- // First pass: count number of servers.
202
- res.server_list.servers.funcs.decode = count_serverlist;
203
- res.server_list.servers.arg = sl;
204
- bool status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res);
205
- if (GPR_UNLIKELY(!status)) {
206
- gpr_free(sl);
207
- gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
208
- return nullptr;
173
+ grpc_error* DropParseAndAppend(
174
+ const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* drop_overload,
175
+ XdsDropConfig* drop_config, bool* drop_all) {
176
+ // Get the category.
177
+ upb_strview category =
178
+ envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_category(
179
+ drop_overload);
180
+ if (category.size == 0) {
181
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty drop category name");
209
182
  }
210
- // Second pass: populate servers.
211
- if (sl->num_servers > 0) {
212
- sl->servers = static_cast<xds_grpclb_server**>(
213
- gpr_zalloc(sizeof(xds_grpclb_server*) * sl->num_servers));
214
- decode_serverlist_arg decode_arg;
215
- memset(&decode_arg, 0, sizeof(decode_arg));
216
- decode_arg.serverlist = sl;
217
- res.server_list.servers.funcs.decode = decode_serverlist;
218
- res.server_list.servers.arg = &decode_arg;
219
- status = pb_decode(&stream_at_start, grpc_lb_v1_LoadBalanceResponse_fields,
220
- &res);
221
- if (GPR_UNLIKELY(!status)) {
222
- xds_grpclb_destroy_serverlist(sl);
223
- gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
224
- return nullptr;
225
- }
183
+ // Get the drop rate (per million).
184
+ const envoy_type_FractionalPercent* drop_percentage =
185
+ envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(
186
+ drop_overload);
187
+ uint32_t numerator = envoy_type_FractionalPercent_numerator(drop_percentage);
188
+ const auto denominator =
189
+ static_cast<envoy_type_FractionalPercent_DenominatorType>(
190
+ envoy_type_FractionalPercent_denominator(drop_percentage));
191
+ // Normalize to million.
192
+ switch (denominator) {
193
+ case envoy_type_FractionalPercent_HUNDRED:
194
+ numerator *= 10000;
195
+ break;
196
+ case envoy_type_FractionalPercent_TEN_THOUSAND:
197
+ numerator *= 100;
198
+ break;
199
+ case envoy_type_FractionalPercent_MILLION:
200
+ break;
201
+ default:
202
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unknown denominator type");
226
203
  }
227
- return sl;
204
+ // Cap numerator to 1000000.
205
+ numerator = GPR_MIN(numerator, 1000000);
206
+ if (numerator == 1000000) *drop_all = true;
207
+ drop_config->AddCategory(StringCopy(category), numerator);
208
+ return GRPC_ERROR_NONE;
228
209
  }
229
210
 
230
- void xds_grpclb_destroy_serverlist(xds_grpclb_serverlist* serverlist) {
231
- if (serverlist == nullptr) {
232
- return;
211
+ } // namespace
212
+
213
+ grpc_error* XdsEdsResponseDecodeAndParse(const grpc_slice& encoded_response,
214
+ XdsUpdate* update) {
215
+ upb::Arena arena;
216
+ // Decode the response.
217
+ const envoy_api_v2_DiscoveryResponse* response =
218
+ envoy_api_v2_DiscoveryResponse_parse(
219
+ reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(encoded_response)),
220
+ GRPC_SLICE_LENGTH(encoded_response), arena.ptr());
221
+ // Parse the response.
222
+ if (response == nullptr) {
223
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No response found.");
233
224
  }
234
- for (size_t i = 0; i < serverlist->num_servers; i++) {
235
- gpr_free(serverlist->servers[i]);
225
+ // Check the type_url of the response.
226
+ upb_strview type_url = envoy_api_v2_DiscoveryResponse_type_url(response);
227
+ upb_strview expected_type_url = upb_strview_makez(kEdsTypeUrl);
228
+ if (!upb_strview_eql(type_url, expected_type_url)) {
229
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resource is not EDS.");
236
230
  }
237
- gpr_free(serverlist->servers);
238
- gpr_free(serverlist);
239
- }
240
-
241
- xds_grpclb_serverlist* xds_grpclb_serverlist_copy(
242
- const xds_grpclb_serverlist* sl) {
243
- xds_grpclb_serverlist* copy = static_cast<xds_grpclb_serverlist*>(
244
- gpr_zalloc(sizeof(xds_grpclb_serverlist)));
245
- copy->num_servers = sl->num_servers;
246
- copy->servers = static_cast<xds_grpclb_server**>(
247
- gpr_malloc(sizeof(xds_grpclb_server*) * sl->num_servers));
248
- for (size_t i = 0; i < sl->num_servers; i++) {
249
- copy->servers[i] =
250
- static_cast<xds_grpclb_server*>(gpr_malloc(sizeof(xds_grpclb_server)));
251
- memcpy(copy->servers[i], sl->servers[i], sizeof(xds_grpclb_server));
231
+ // Get the resources from the response.
232
+ size_t size;
233
+ const google_protobuf_Any* const* resources =
234
+ envoy_api_v2_DiscoveryResponse_resources(response, &size);
235
+ if (size < 1) {
236
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
237
+ "EDS response contains 0 resource.");
252
238
  }
253
- return copy;
254
- }
255
-
256
- bool xds_grpclb_serverlist_equals(const xds_grpclb_serverlist* lhs,
257
- const xds_grpclb_serverlist* rhs) {
258
- if (lhs == nullptr || rhs == nullptr) {
259
- return false;
239
+ // Check the type_url of the resource.
240
+ type_url = google_protobuf_Any_type_url(resources[0]);
241
+ if (!upb_strview_eql(type_url, expected_type_url)) {
242
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resource is not EDS.");
260
243
  }
261
- if (lhs->num_servers != rhs->num_servers) {
262
- return false;
244
+ // Get the cluster_load_assignment.
245
+ upb_strview encoded_cluster_load_assignment =
246
+ google_protobuf_Any_value(resources[0]);
247
+ envoy_api_v2_ClusterLoadAssignment* cluster_load_assignment =
248
+ envoy_api_v2_ClusterLoadAssignment_parse(
249
+ encoded_cluster_load_assignment.data,
250
+ encoded_cluster_load_assignment.size, arena.ptr());
251
+ // Get the endpoints.
252
+ const envoy_api_v2_endpoint_LocalityLbEndpoints* const* endpoints =
253
+ envoy_api_v2_ClusterLoadAssignment_endpoints(cluster_load_assignment,
254
+ &size);
255
+ for (size_t i = 0; i < size; ++i) {
256
+ XdsLocalityInfo locality_info;
257
+ grpc_error* error = LocalityParse(endpoints[i], &locality_info);
258
+ if (error != GRPC_ERROR_NONE) return error;
259
+ // Filter out locality with weight 0.
260
+ if (locality_info.lb_weight == 0) continue;
261
+ update->locality_list.push_back(std::move(locality_info));
263
262
  }
264
- for (size_t i = 0; i < lhs->num_servers; i++) {
265
- if (!xds_grpclb_server_equals(lhs->servers[i], rhs->servers[i])) {
266
- return false;
263
+ // The locality list is sorted here into deterministic order so that it's
264
+ // easier to check if two locality lists contain the same set of localities.
265
+ std::sort(update->locality_list.data(),
266
+ update->locality_list.data() + update->locality_list.size(),
267
+ XdsLocalityInfo::Less());
268
+ // Get the drop config.
269
+ update->drop_config = MakeRefCounted<XdsDropConfig>();
270
+ const envoy_api_v2_ClusterLoadAssignment_Policy* policy =
271
+ envoy_api_v2_ClusterLoadAssignment_policy(cluster_load_assignment);
272
+ if (policy != nullptr) {
273
+ const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* const*
274
+ drop_overload =
275
+ envoy_api_v2_ClusterLoadAssignment_Policy_drop_overloads(policy,
276
+ &size);
277
+ for (size_t i = 0; i < size; ++i) {
278
+ grpc_error* error = DropParseAndAppend(
279
+ drop_overload[i], update->drop_config.get(), &update->drop_all);
280
+ if (error != GRPC_ERROR_NONE) return error;
267
281
  }
268
282
  }
269
- return true;
283
+ return GRPC_ERROR_NONE;
270
284
  }
271
285
 
272
- bool xds_grpclb_server_equals(const xds_grpclb_server* lhs,
273
- const xds_grpclb_server* rhs) {
274
- return memcmp(lhs, rhs, sizeof(xds_grpclb_server)) == 0;
286
+ namespace {
287
+
288
+ grpc_slice LrsRequestEncode(
289
+ const envoy_service_load_stats_v2_LoadStatsRequest* request,
290
+ upb_arena* arena) {
291
+ size_t output_length;
292
+ char* output = envoy_service_load_stats_v2_LoadStatsRequest_serialize(
293
+ request, arena, &output_length);
294
+ return grpc_slice_from_copied_buffer(output, output_length);
275
295
  }
276
296
 
277
- int xds_grpclb_duration_compare(const xds_grpclb_duration* lhs,
278
- const xds_grpclb_duration* rhs) {
279
- GPR_ASSERT(lhs && rhs);
280
- if (lhs->has_seconds && rhs->has_seconds) {
281
- if (lhs->seconds < rhs->seconds) return -1;
282
- if (lhs->seconds > rhs->seconds) return 1;
283
- } else if (lhs->has_seconds) {
284
- return 1;
285
- } else if (rhs->has_seconds) {
286
- return -1;
287
- }
297
+ } // namespace
288
298
 
289
- GPR_ASSERT(lhs->seconds == rhs->seconds);
290
- if (lhs->has_nanos && rhs->has_nanos) {
291
- if (lhs->nanos < rhs->nanos) return -1;
292
- if (lhs->nanos > rhs->nanos) return 1;
293
- } else if (lhs->has_nanos) {
294
- return 1;
295
- } else if (rhs->has_nanos) {
296
- return -1;
297
- }
299
+ grpc_slice XdsLrsRequestCreateAndEncode(const char* server_name) {
300
+ upb::Arena arena;
301
+ // Create a request.
302
+ envoy_service_load_stats_v2_LoadStatsRequest* request =
303
+ envoy_service_load_stats_v2_LoadStatsRequest_new(arena.ptr());
304
+ // Add cluster stats. There is only one because we only use one server name in
305
+ // one channel.
306
+ envoy_api_v2_endpoint_ClusterStats* cluster_stats =
307
+ envoy_service_load_stats_v2_LoadStatsRequest_add_cluster_stats(
308
+ request, arena.ptr());
309
+ // Set the cluster name.
310
+ envoy_api_v2_endpoint_ClusterStats_set_cluster_name(
311
+ cluster_stats, upb_strview_makez(server_name));
312
+ return LrsRequestEncode(request, arena.ptr());
313
+ }
314
+
315
+ namespace {
298
316
 
299
- return 0;
317
+ void LocalityStatsPopulate(envoy_api_v2_endpoint_UpstreamLocalityStats* output,
318
+ #if GRPC_USE_CPP_STD_LIB
319
+ // TODO(veblush): Clean up this
320
+ // This is to address the difference between
321
+ // std::map and Map. #else block will be gone
322
+ // once using stdlib is enabled by default.
323
+ Pair<const RefCountedPtr<XdsLocalityName>,
324
+ #else
325
+ Pair<RefCountedPtr<XdsLocalityName>,
326
+ #endif
327
+ XdsClientStats::LocalityStats::Snapshot>& input,
328
+ upb_arena* arena) {
329
+ // Set sub_zone.
330
+ envoy_api_v2_core_Locality* locality =
331
+ envoy_api_v2_endpoint_UpstreamLocalityStats_mutable_locality(output,
332
+ arena);
333
+ envoy_api_v2_core_Locality_set_sub_zone(
334
+ locality, upb_strview_makez(input.first->sub_zone()));
335
+ // Set total counts.
336
+ XdsClientStats::LocalityStats::Snapshot& snapshot = input.second;
337
+ envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_successful_requests(
338
+ output, snapshot.total_successful_requests);
339
+ envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_requests_in_progress(
340
+ output, snapshot.total_requests_in_progress);
341
+ envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_error_requests(
342
+ output, snapshot.total_error_requests);
343
+ envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_issued_requests(
344
+ output, snapshot.total_issued_requests);
345
+ // Add load metric stats.
346
+ for (auto& p : snapshot.load_metric_stats) {
347
+ const char* metric_name = p.first.get();
348
+ const XdsClientStats::LocalityStats::LoadMetric::Snapshot& metric_value =
349
+ p.second;
350
+ envoy_api_v2_endpoint_EndpointLoadMetricStats* load_metric =
351
+ envoy_api_v2_endpoint_UpstreamLocalityStats_add_load_metric_stats(
352
+ output, arena);
353
+ envoy_api_v2_endpoint_EndpointLoadMetricStats_set_metric_name(
354
+ load_metric, upb_strview_makez(metric_name));
355
+ envoy_api_v2_endpoint_EndpointLoadMetricStats_set_num_requests_finished_with_metric(
356
+ load_metric, metric_value.num_requests_finished_with_metric);
357
+ envoy_api_v2_endpoint_EndpointLoadMetricStats_set_total_metric_value(
358
+ load_metric, metric_value.total_metric_value);
359
+ }
300
360
  }
301
361
 
302
- grpc_millis xds_grpclb_duration_to_millis(xds_grpclb_duration* duration_pb) {
303
- return static_cast<grpc_millis>(
304
- (duration_pb->has_seconds ? duration_pb->seconds : 0) * GPR_MS_PER_SEC +
305
- (duration_pb->has_nanos ? duration_pb->nanos : 0) / GPR_NS_PER_MS);
362
+ } // namespace
363
+
364
+ grpc_slice XdsLrsRequestCreateAndEncode(const char* server_name,
365
+ XdsClientStats* client_stats) {
366
+ upb::Arena arena;
367
+ XdsClientStats::Snapshot snapshot = client_stats->GetSnapshotAndReset();
368
+ // Prune unused locality stats.
369
+ client_stats->PruneLocalityStats();
370
+ // When all the counts are zero, return empty slice.
371
+ if (snapshot.IsAllZero()) return grpc_empty_slice();
372
+ // Create a request.
373
+ envoy_service_load_stats_v2_LoadStatsRequest* request =
374
+ envoy_service_load_stats_v2_LoadStatsRequest_new(arena.ptr());
375
+ // Add cluster stats. There is only one because we only use one server name in
376
+ // one channel.
377
+ envoy_api_v2_endpoint_ClusterStats* cluster_stats =
378
+ envoy_service_load_stats_v2_LoadStatsRequest_add_cluster_stats(
379
+ request, arena.ptr());
380
+ // Set the cluster name.
381
+ envoy_api_v2_endpoint_ClusterStats_set_cluster_name(
382
+ cluster_stats, upb_strview_makez(server_name));
383
+ // Add locality stats.
384
+ for (auto& p : snapshot.upstream_locality_stats) {
385
+ envoy_api_v2_endpoint_UpstreamLocalityStats* locality_stats =
386
+ envoy_api_v2_endpoint_ClusterStats_add_upstream_locality_stats(
387
+ cluster_stats, arena.ptr());
388
+ LocalityStatsPopulate(locality_stats, p, arena.ptr());
389
+ }
390
+ // Add dropped requests.
391
+ for (auto& p : snapshot.dropped_requests) {
392
+ const char* category = p.first.get();
393
+ const uint64_t count = p.second;
394
+ envoy_api_v2_endpoint_ClusterStats_DroppedRequests* dropped_requests =
395
+ envoy_api_v2_endpoint_ClusterStats_add_dropped_requests(cluster_stats,
396
+ arena.ptr());
397
+ envoy_api_v2_endpoint_ClusterStats_DroppedRequests_set_category(
398
+ dropped_requests, upb_strview_makez(category));
399
+ envoy_api_v2_endpoint_ClusterStats_DroppedRequests_set_dropped_count(
400
+ dropped_requests, count);
401
+ }
402
+ // Set total dropped requests.
403
+ envoy_api_v2_endpoint_ClusterStats_set_total_dropped_requests(
404
+ cluster_stats, snapshot.total_dropped_requests);
405
+ // Set real load report interval.
406
+ gpr_timespec timespec =
407
+ grpc_millis_to_timespec(snapshot.load_report_interval, GPR_TIMESPAN);
408
+ google_protobuf_Duration* load_report_interval =
409
+ envoy_api_v2_endpoint_ClusterStats_mutable_load_report_interval(
410
+ cluster_stats, arena.ptr());
411
+ google_protobuf_Duration_set_seconds(load_report_interval, timespec.tv_sec);
412
+ google_protobuf_Duration_set_nanos(load_report_interval, timespec.tv_nsec);
413
+ return LrsRequestEncode(request, arena.ptr());
306
414
  }
307
415
 
308
- void xds_grpclb_initial_response_destroy(
309
- xds_grpclb_initial_response* response) {
310
- gpr_free(response);
416
+ grpc_error* XdsLrsResponseDecodeAndParse(const grpc_slice& encoded_response,
417
+ grpc_millis* load_reporting_interval,
418
+ const char* expected_server_name) {
419
+ upb::Arena arena;
420
+ // Decode the response.
421
+ const envoy_service_load_stats_v2_LoadStatsResponse* decoded_response =
422
+ envoy_service_load_stats_v2_LoadStatsResponse_parse(
423
+ reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(encoded_response)),
424
+ GRPC_SLICE_LENGTH(encoded_response), arena.ptr());
425
+ // Parse the response.
426
+ if (decoded_response == nullptr) {
427
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No response found.");
428
+ }
429
+ // Check the cluster size in the response.
430
+ size_t size;
431
+ const upb_strview* clusters =
432
+ envoy_service_load_stats_v2_LoadStatsResponse_clusters(decoded_response,
433
+ &size);
434
+ if (size != 1) {
435
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
436
+ "The number of clusters (server names) is not 1.");
437
+ }
438
+ // Check the cluster name in the response
439
+ if (strncmp(expected_server_name, clusters[0].data, clusters[0].size) != 0) {
440
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
441
+ "Unexpected cluster (server name).");
442
+ }
443
+ // Get the load report interval.
444
+ const google_protobuf_Duration* load_reporting_interval_duration =
445
+ envoy_service_load_stats_v2_LoadStatsResponse_load_reporting_interval(
446
+ decoded_response);
447
+ gpr_timespec timespec{
448
+ google_protobuf_Duration_seconds(load_reporting_interval_duration),
449
+ google_protobuf_Duration_nanos(load_reporting_interval_duration),
450
+ GPR_TIMESPAN};
451
+ *load_reporting_interval = gpr_time_to_millis(timespec);
452
+ return GRPC_ERROR_NONE;
311
453
  }
454
+
455
+ } // namespace grpc_core