grpc 1.43.1 → 1.44.0.pre2

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 (382) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +84 -64
  3. data/include/grpc/grpc_security.h +10 -0
  4. data/include/grpc/impl/codegen/compression_types.h +0 -2
  5. data/include/grpc/impl/codegen/grpc_types.h +6 -0
  6. data/src/core/ext/filters/client_channel/backend_metric.h +1 -1
  7. data/src/core/ext/filters/client_channel/client_channel.cc +62 -68
  8. data/src/core/ext/filters/client_channel/client_channel.h +8 -8
  9. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +1 -1
  10. data/src/core/ext/filters/client_channel/config_selector.h +4 -4
  11. data/src/core/ext/filters/client_channel/dynamic_filters.h +1 -1
  12. data/src/core/ext/filters/client_channel/health/health_check_client.cc +16 -14
  13. data/src/core/ext/filters/client_channel/health/health_check_client.h +3 -3
  14. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -1
  15. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +4 -3
  16. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +6 -5
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +3 -7
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +31 -32
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +0 -7
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +1 -1
  21. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +1 -1
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +43 -29
  24. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +6 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +120 -68
  26. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +60 -48
  27. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +62 -61
  28. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +16 -11
  29. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -5
  30. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +19 -15
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.h +1 -1
  32. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +14 -12
  33. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +3 -2
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +50 -105
  35. data/src/core/ext/filters/client_channel/lb_policy.cc +15 -14
  36. data/src/core/ext/filters/client_channel/lb_policy.h +19 -3
  37. data/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +3 -3
  38. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +207 -81
  39. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +22 -12
  40. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +19 -15
  41. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +23 -38
  42. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +118 -207
  43. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +25 -32
  44. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +1 -1
  45. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +82 -73
  46. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +10 -10
  47. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +2 -1
  48. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -5
  49. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +5 -5
  50. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +157 -67
  51. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +1 -1
  52. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +2 -2
  53. data/src/core/ext/filters/client_channel/retry_filter.cc +37 -64
  54. data/src/core/ext/filters/client_channel/retry_service_config.cc +1 -1
  55. data/src/core/ext/filters/client_channel/retry_service_config.h +1 -1
  56. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +1 -1
  57. data/src/core/ext/filters/client_channel/subchannel.cc +12 -16
  58. data/src/core/ext/filters/client_channel/subchannel.h +2 -3
  59. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +37 -48
  60. data/src/core/ext/filters/fault_injection/service_config_parser.cc +6 -8
  61. data/src/core/ext/filters/fault_injection/service_config_parser.h +1 -1
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +51 -122
  63. data/src/core/ext/filters/http/client_authority_filter.cc +8 -24
  64. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +42 -140
  65. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +5 -25
  66. data/src/core/ext/filters/http/server/http_server_filter.cc +50 -135
  67. data/src/core/ext/filters/message_size/message_size_filter.cc +1 -1
  68. data/src/core/ext/filters/message_size/message_size_filter.h +1 -1
  69. data/src/core/ext/filters/rbac/rbac_filter.cc +157 -0
  70. data/src/core/ext/filters/rbac/rbac_filter.h +74 -0
  71. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +605 -0
  72. data/src/core/ext/filters/rbac/rbac_service_config_parser.h +70 -0
  73. data/src/core/ext/filters/server_config_selector/server_config_selector.h +3 -2
  74. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +11 -6
  75. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +1 -1
  76. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +1 -1
  77. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +89 -29
  78. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +0 -1
  79. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +45 -186
  80. data/src/core/ext/transport/chttp2/transport/frame_data.cc +0 -1
  81. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +341 -279
  82. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +69 -159
  83. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +1 -1
  84. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.h +2 -0
  85. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +19 -32
  86. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -1
  87. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +94 -1
  88. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +2 -24
  89. data/src/core/ext/transport/chttp2/transport/internal.h +0 -33
  90. data/src/core/ext/transport/chttp2/transport/parsing.cc +0 -6
  91. data/src/core/ext/transport/chttp2/transport/writing.cc +47 -116
  92. data/src/core/ext/transport/inproc/inproc_plugin.cc +0 -4
  93. data/src/core/ext/transport/inproc/inproc_transport.cc +11 -63
  94. data/src/core/ext/transport/inproc/inproc_transport.h +0 -3
  95. data/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c +61 -0
  96. data/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.h +146 -0
  97. data/src/core/ext/upbdefs-generated/envoy/config/rbac/v3/rbac.upbdefs.c +188 -0
  98. data/src/core/ext/upbdefs-generated/envoy/config/rbac/v3/rbac.upbdefs.h +70 -0
  99. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c +56 -0
  100. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.h +40 -0
  101. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/checked.upbdefs.c +154 -0
  102. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/checked.upbdefs.h +95 -0
  103. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/eval.upbdefs.c +58 -0
  104. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/eval.upbdefs.h +55 -0
  105. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/explain.upbdefs.c +44 -0
  106. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/explain.upbdefs.h +40 -0
  107. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/syntax.upbdefs.c +153 -0
  108. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/syntax.upbdefs.h +100 -0
  109. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/value.upbdefs.c +75 -0
  110. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/value.upbdefs.h +55 -0
  111. data/src/core/ext/xds/upb_utils.h +65 -0
  112. data/src/core/ext/xds/xds_api.cc +81 -3458
  113. data/src/core/ext/xds/xds_api.h +56 -611
  114. data/src/core/ext/xds/xds_bootstrap.cc +189 -125
  115. data/src/core/ext/xds/xds_bootstrap.h +20 -15
  116. data/src/core/ext/xds/xds_certificate_provider.h +1 -0
  117. data/src/core/ext/xds/xds_channel_creds.cc +108 -0
  118. data/src/core/ext/xds/xds_channel_creds.h +50 -0
  119. data/src/core/ext/xds/xds_client.cc +584 -994
  120. data/src/core/ext/xds/xds_client.h +78 -135
  121. data/src/core/ext/xds/xds_cluster.cc +451 -0
  122. data/src/core/ext/xds/xds_cluster.h +111 -0
  123. data/src/core/ext/xds/xds_common_types.cc +388 -0
  124. data/src/core/ext/xds/xds_common_types.h +110 -0
  125. data/src/core/ext/xds/xds_endpoint.cc +364 -0
  126. data/src/core/ext/xds/xds_endpoint.h +135 -0
  127. data/src/core/ext/xds/xds_http_filters.cc +5 -0
  128. data/src/core/ext/xds/xds_http_rbac_filter.cc +563 -0
  129. data/src/core/ext/xds/xds_http_rbac_filter.h +54 -0
  130. data/src/core/ext/xds/xds_listener.cc +1036 -0
  131. data/src/core/ext/xds/xds_listener.h +220 -0
  132. data/src/core/ext/{transport/chttp2/transport/hpack_utils.h → xds/xds_resource_type.cc} +12 -9
  133. data/src/core/ext/xds/xds_resource_type.h +98 -0
  134. data/src/core/ext/xds/xds_resource_type_impl.h +87 -0
  135. data/src/core/ext/xds/xds_route_config.cc +993 -0
  136. data/src/core/ext/xds/xds_route_config.h +215 -0
  137. data/src/core/ext/xds/xds_routing.cc +11 -8
  138. data/src/core/ext/xds/xds_routing.h +8 -5
  139. data/src/core/ext/xds/xds_server_config_fetcher.cc +159 -99
  140. data/src/core/lib/address_utils/parse_address.cc +20 -0
  141. data/src/core/lib/address_utils/parse_address.h +5 -0
  142. data/src/core/lib/address_utils/sockaddr_utils.cc +33 -36
  143. data/src/core/lib/address_utils/sockaddr_utils.h +1 -16
  144. data/src/core/lib/backoff/backoff.cc +4 -30
  145. data/src/core/lib/backoff/backoff.h +3 -3
  146. data/src/core/lib/channel/channel_args.cc +0 -1
  147. data/src/core/lib/channel/channel_stack.cc +8 -0
  148. data/src/core/lib/channel/channel_stack.h +1 -1
  149. data/src/core/lib/channel/channel_stack_builder.cc +5 -9
  150. data/src/core/lib/channel/channel_stack_builder.h +4 -7
  151. data/src/core/lib/channel/channelz.cc +1 -0
  152. data/src/core/lib/compression/compression.cc +19 -111
  153. data/src/core/lib/compression/compression_internal.cc +142 -202
  154. data/src/core/lib/compression/compression_internal.h +64 -69
  155. data/src/core/lib/compression/message_compress.cc +11 -11
  156. data/src/core/lib/compression/message_compress.h +2 -2
  157. data/src/core/lib/gpr/useful.h +4 -0
  158. data/src/core/lib/gprpp/bitset.h +7 -0
  159. data/src/core/lib/gprpp/chunked_vector.h +45 -3
  160. data/src/core/lib/gprpp/status_helper.cc +20 -28
  161. data/src/core/lib/gprpp/status_helper.h +6 -19
  162. data/src/core/lib/gprpp/table.h +11 -0
  163. data/src/core/lib/http/httpcli.cc +37 -46
  164. data/src/core/lib/http/httpcli.h +3 -15
  165. data/src/core/lib/iomgr/call_combiner.cc +15 -4
  166. data/src/core/lib/iomgr/closure.h +29 -9
  167. data/src/core/lib/iomgr/combiner.cc +25 -3
  168. data/src/core/lib/iomgr/error.cc +2 -0
  169. data/src/core/lib/iomgr/error.h +3 -0
  170. data/src/core/lib/iomgr/event_engine/iomgr.cc +3 -2
  171. data/src/core/lib/iomgr/event_engine/resolved_address_internal.cc +6 -0
  172. data/src/core/lib/iomgr/event_engine/resolved_address_internal.h +2 -0
  173. data/src/core/lib/iomgr/event_engine/resolver.cc +66 -48
  174. data/src/core/lib/iomgr/event_engine/resolver.h +56 -0
  175. data/src/core/lib/iomgr/exec_ctx.cc +22 -9
  176. data/src/core/lib/iomgr/executor.cc +10 -1
  177. data/src/core/lib/iomgr/fork_posix.cc +3 -2
  178. data/src/core/lib/iomgr/iomgr_custom.cc +4 -1
  179. data/src/core/lib/iomgr/iomgr_posix.cc +2 -2
  180. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +2 -2
  181. data/src/core/lib/iomgr/iomgr_windows.cc +2 -2
  182. data/src/core/lib/iomgr/port.h +2 -2
  183. data/src/core/lib/iomgr/resolve_address.cc +5 -24
  184. data/src/core/lib/iomgr/resolve_address.h +47 -44
  185. data/src/core/lib/iomgr/resolve_address_custom.cc +131 -109
  186. data/src/core/lib/iomgr/resolve_address_custom.h +101 -19
  187. data/src/core/lib/iomgr/resolve_address_impl.h +59 -0
  188. data/src/core/lib/iomgr/resolve_address_posix.cc +82 -66
  189. data/src/core/lib/iomgr/resolve_address_posix.h +47 -0
  190. data/src/core/lib/iomgr/resolve_address_windows.cc +93 -74
  191. data/src/core/lib/iomgr/resolve_address_windows.h +47 -0
  192. data/src/core/lib/iomgr/resolved_address.h +39 -0
  193. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +1 -0
  194. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +1 -0
  195. data/src/core/lib/iomgr/unix_sockets_posix.cc +22 -34
  196. data/src/core/lib/iomgr/unix_sockets_posix.h +4 -7
  197. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +6 -15
  198. data/src/core/lib/matchers/matchers.cc +1 -1
  199. data/src/core/lib/promise/activity.h +49 -20
  200. data/src/core/lib/promise/detail/status.h +5 -0
  201. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver.cc +17 -25
  202. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver.h +43 -44
  203. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_factory.h +10 -5
  204. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_registry.cc +3 -2
  205. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_registry.h +4 -5
  206. data/src/core/{ext/filters/client_channel → lib/resolver}/server_address.cc +1 -1
  207. data/src/core/{ext/filters/client_channel → lib/resolver}/server_address.h +4 -4
  208. data/src/core/lib/resource_quota/api.h +0 -1
  209. data/src/core/lib/{gprpp → resource_quota}/arena.cc +16 -13
  210. data/src/core/lib/{gprpp → resource_quota}/arena.h +24 -13
  211. data/src/core/lib/security/authorization/evaluate_args.cc +30 -15
  212. data/src/core/lib/security/authorization/evaluate_args.h +1 -0
  213. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +60 -0
  214. data/src/core/lib/security/authorization/grpc_authorization_engine.h +62 -0
  215. data/src/core/lib/security/authorization/matchers.cc +227 -0
  216. data/src/core/lib/security/authorization/matchers.h +211 -0
  217. data/src/core/lib/security/authorization/rbac_policy.cc +442 -0
  218. data/src/core/lib/security/authorization/rbac_policy.h +170 -0
  219. data/src/core/lib/security/context/security_context.cc +4 -2
  220. data/src/core/lib/security/context/security_context.h +1 -1
  221. data/src/core/lib/security/credentials/composite/composite_credentials.cc +5 -5
  222. data/src/core/lib/security/credentials/composite/composite_credentials.h +4 -3
  223. data/src/core/lib/security/credentials/credentials.h +10 -20
  224. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +6 -9
  225. data/src/core/lib/security/credentials/external/external_account_credentials.cc +7 -9
  226. data/src/core/lib/security/credentials/external/external_account_credentials.h +2 -7
  227. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +2 -3
  228. data/src/core/lib/security/credentials/fake/fake_credentials.cc +5 -4
  229. data/src/core/lib/security/credentials/fake/fake_credentials.h +8 -7
  230. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +2 -5
  231. data/src/core/lib/security/credentials/iam/iam_credentials.cc +16 -19
  232. data/src/core/lib/security/credentials/iam/iam_credentials.h +6 -5
  233. data/src/core/lib/security/credentials/jwt/json_token.cc +4 -6
  234. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +16 -28
  235. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +8 -8
  236. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +6 -13
  237. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +44 -57
  238. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +13 -15
  239. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -7
  240. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +5 -4
  241. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +1 -10
  242. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +6 -0
  243. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +7 -0
  244. data/src/core/lib/security/credentials/xds/xds_credentials.h +1 -1
  245. data/src/core/lib/security/security_connector/security_connector.cc +0 -4
  246. data/src/core/lib/security/security_connector/security_connector.h +5 -1
  247. data/src/core/lib/security/security_connector/ssl_utils.cc +14 -24
  248. data/src/core/lib/security/security_connector/ssl_utils.h +5 -14
  249. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +2 -3
  250. data/src/core/lib/security/transport/auth_filters.h +7 -0
  251. data/src/core/lib/security/transport/client_auth_filter.cc +53 -33
  252. data/src/core/lib/security/transport/server_auth_filter.cc +40 -35
  253. data/src/core/{ext → lib}/service_config/service_config.cc +2 -2
  254. data/src/core/{ext → lib}/service_config/service_config.h +4 -4
  255. data/src/core/{ext → lib}/service_config/service_config_call_data.h +5 -5
  256. data/src/core/{ext → lib}/service_config/service_config_parser.cc +1 -1
  257. data/src/core/{ext → lib}/service_config/service_config_parser.h +3 -3
  258. data/src/core/lib/slice/slice.cc +3 -1
  259. data/src/core/lib/slice/slice.h +43 -13
  260. data/src/core/lib/slice/slice_intern.cc +3 -101
  261. data/src/core/lib/slice/slice_internal.h +1 -2
  262. data/src/core/lib/slice/slice_refcount.h +4 -13
  263. data/src/core/lib/slice/slice_refcount_base.h +0 -16
  264. data/src/core/lib/surface/call.cc +140 -382
  265. data/src/core/lib/surface/call.h +4 -4
  266. data/src/core/lib/surface/channel.cc +42 -44
  267. data/src/core/lib/surface/channel.h +4 -4
  268. data/src/core/lib/surface/init.cc +0 -2
  269. data/src/core/lib/surface/lame_client.cc +0 -1
  270. data/src/core/lib/surface/server.cc +12 -29
  271. data/src/core/lib/surface/server.h +2 -2
  272. data/src/core/lib/surface/version.cc +2 -2
  273. data/src/core/lib/transport/error_utils.h +14 -0
  274. data/src/core/lib/transport/metadata_batch.h +799 -717
  275. data/src/core/lib/transport/parsed_metadata.cc +2 -0
  276. data/src/core/lib/transport/parsed_metadata.h +95 -92
  277. data/src/core/lib/transport/timeout_encoding.cc +200 -66
  278. data/src/core/lib/transport/timeout_encoding.h +40 -10
  279. data/src/core/lib/transport/transport.h +1 -1
  280. data/src/core/lib/transport/transport_op_string.cc +6 -39
  281. data/src/core/lib/uri/uri_parser.cc +223 -53
  282. data/src/core/lib/uri/uri_parser.h +36 -23
  283. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -3
  284. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  285. data/src/core/tsi/ssl/session_cache/ssl_session.h +2 -4
  286. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +3 -5
  287. data/src/core/tsi/ssl_transport_security.cc +53 -13
  288. data/src/core/tsi/ssl_transport_security.h +18 -6
  289. data/src/ruby/ext/grpc/extconf.rb +10 -3
  290. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  291. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  292. data/src/ruby/lib/grpc/version.rb +1 -1
  293. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +2 -1
  294. data/third_party/abseil-cpp/absl/base/internal/fast_type_id.h +48 -0
  295. data/third_party/abseil-cpp/absl/random/bernoulli_distribution.h +200 -0
  296. data/third_party/abseil-cpp/absl/random/beta_distribution.h +427 -0
  297. data/third_party/abseil-cpp/absl/random/discrete_distribution.cc +98 -0
  298. data/third_party/abseil-cpp/absl/random/discrete_distribution.h +247 -0
  299. data/third_party/abseil-cpp/absl/random/distributions.h +452 -0
  300. data/third_party/abseil-cpp/absl/random/exponential_distribution.h +165 -0
  301. data/third_party/abseil-cpp/absl/random/gaussian_distribution.cc +104 -0
  302. data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +275 -0
  303. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +92 -0
  304. data/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h +268 -0
  305. data/third_party/abseil-cpp/absl/random/internal/fastmath.h +57 -0
  306. data/third_party/abseil-cpp/absl/random/internal/generate_real.h +144 -0
  307. data/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h +245 -0
  308. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +150 -0
  309. data/third_party/abseil-cpp/absl/random/internal/pcg_engine.h +308 -0
  310. data/third_party/abseil-cpp/absl/random/internal/platform.h +171 -0
  311. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.cc +253 -0
  312. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +131 -0
  313. data/third_party/abseil-cpp/absl/random/internal/randen.cc +91 -0
  314. data/third_party/abseil-cpp/absl/random/internal/randen.h +102 -0
  315. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +221 -0
  316. data/third_party/abseil-cpp/absl/random/internal/randen_detect.h +33 -0
  317. data/third_party/abseil-cpp/absl/random/internal/randen_engine.h +239 -0
  318. data/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc +526 -0
  319. data/third_party/abseil-cpp/absl/random/internal/randen_hwaes.h +50 -0
  320. data/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc +462 -0
  321. data/third_party/abseil-cpp/absl/random/internal/randen_slow.cc +471 -0
  322. data/third_party/abseil-cpp/absl/random/internal/randen_slow.h +40 -0
  323. data/third_party/abseil-cpp/absl/random/internal/randen_traits.h +88 -0
  324. data/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h +167 -0
  325. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +267 -0
  326. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +104 -0
  327. data/third_party/abseil-cpp/absl/random/internal/traits.h +101 -0
  328. data/third_party/abseil-cpp/absl/random/internal/uniform_helper.h +244 -0
  329. data/third_party/abseil-cpp/absl/random/internal/wide_multiply.h +111 -0
  330. data/third_party/abseil-cpp/absl/random/log_uniform_int_distribution.h +257 -0
  331. data/third_party/abseil-cpp/absl/random/poisson_distribution.h +258 -0
  332. data/third_party/abseil-cpp/absl/random/random.h +189 -0
  333. data/third_party/abseil-cpp/absl/random/seed_gen_exception.cc +46 -0
  334. data/third_party/abseil-cpp/absl/random/seed_gen_exception.h +55 -0
  335. data/third_party/abseil-cpp/absl/random/seed_sequences.cc +29 -0
  336. data/third_party/abseil-cpp/absl/random/seed_sequences.h +110 -0
  337. data/third_party/abseil-cpp/absl/random/uniform_int_distribution.h +275 -0
  338. data/third_party/abseil-cpp/absl/random/uniform_real_distribution.h +202 -0
  339. data/third_party/abseil-cpp/absl/random/zipf_distribution.h +271 -0
  340. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_enc.c +1 -0
  341. data/third_party/boringssl-with-bazel/src/crypto/base64/base64.c +13 -0
  342. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa.c +21 -0
  343. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/cipher.c +12 -0
  344. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/ecdsa.c +1 -2
  345. data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +2 -2
  346. data/third_party/boringssl-with-bazel/src/crypto/mem.c +1 -1
  347. data/third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7.c +29 -0
  348. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/internal.h +0 -1
  349. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8.c +1 -1
  350. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8_x509.c +1 -1
  351. data/third_party/boringssl-with-bazel/src/include/openssl/base64.h +8 -0
  352. data/third_party/boringssl-with-bazel/src/include/openssl/cipher.h +13 -1
  353. data/third_party/boringssl-with-bazel/src/include/openssl/dsa.h +10 -0
  354. data/third_party/boringssl-with-bazel/src/include/openssl/hpke.h +1 -1
  355. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs7.h +9 -4
  356. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs8.h +6 -1
  357. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +23 -2
  358. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +4 -0
  359. data/third_party/xxhash/xxhash.h +607 -352
  360. metadata +149 -77
  361. data/src/core/ext/transport/chttp2/transport/hpack_encoder_index.h +0 -107
  362. data/src/core/ext/transport/chttp2/transport/hpack_utils.cc +0 -46
  363. data/src/core/ext/transport/chttp2/transport/popularity_count.h +0 -60
  364. data/src/core/lib/compression/algorithm_metadata.h +0 -62
  365. data/src/core/lib/compression/compression_args.cc +0 -140
  366. data/src/core/lib/compression/compression_args.h +0 -58
  367. data/src/core/lib/compression/stream_compression.cc +0 -81
  368. data/src/core/lib/compression/stream_compression.h +0 -117
  369. data/src/core/lib/compression/stream_compression_gzip.cc +0 -231
  370. data/src/core/lib/compression/stream_compression_gzip.h +0 -28
  371. data/src/core/lib/compression/stream_compression_identity.cc +0 -91
  372. data/src/core/lib/compression/stream_compression_identity.h +0 -29
  373. data/src/core/lib/security/credentials/credentials_metadata.cc +0 -61
  374. data/src/core/lib/slice/static_slice.cc +0 -377
  375. data/src/core/lib/slice/static_slice.h +0 -300
  376. data/src/core/lib/transport/metadata.cc +0 -714
  377. data/src/core/lib/transport/metadata.h +0 -449
  378. data/src/core/lib/transport/metadata_batch.cc +0 -99
  379. data/src/core/lib/transport/static_metadata.cc +0 -1032
  380. data/src/core/lib/transport/static_metadata.h +0 -322
  381. data/src/core/lib/transport/status_metadata.cc +0 -63
  382. data/src/core/lib/transport/status_metadata.h +0 -48
@@ -36,8 +36,12 @@
36
36
  #include "src/core/ext/xds/xds_api.h"
37
37
  #include "src/core/ext/xds/xds_bootstrap.h"
38
38
  #include "src/core/ext/xds/xds_channel_args.h"
39
+ #include "src/core/ext/xds/xds_channel_creds.h"
39
40
  #include "src/core/ext/xds/xds_client_stats.h"
41
+ #include "src/core/ext/xds/xds_cluster.h"
42
+ #include "src/core/ext/xds/xds_endpoint.h"
40
43
  #include "src/core/ext/xds/xds_http_filters.h"
44
+ #include "src/core/ext/xds/xds_listener.h"
41
45
  #include "src/core/lib/address_utils/sockaddr_utils.h"
42
46
  #include "src/core/lib/backoff/backoff.h"
43
47
  #include "src/core/lib/channel/channel_args.h"
@@ -54,7 +58,6 @@
54
58
  #include "src/core/lib/slice/slice_string_helpers.h"
55
59
  #include "src/core/lib/surface/call.h"
56
60
  #include "src/core/lib/surface/channel.h"
57
- #include "src/core/lib/transport/static_metadata.h"
58
61
  #include "src/core/lib/uri/uri_parser.h"
59
62
 
60
63
  #define GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS 1
@@ -172,21 +175,53 @@ class XdsClient::ChannelState::AdsCallState
172
175
  XdsClient* xds_client() const { return chand()->xds_client(); }
173
176
  bool seen_response() const { return seen_response_; }
174
177
 
175
- void SubscribeLocked(const std::string& type_url,
176
- const XdsApi::ResourceName& name)
178
+ void SubscribeLocked(const XdsResourceType* type, const XdsResourceName& name)
177
179
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
178
- void UnsubscribeLocked(const std::string& type_url,
179
- const XdsApi::ResourceName& name,
180
- bool delay_unsubscription)
180
+ void UnsubscribeLocked(const XdsResourceType* type,
181
+ const XdsResourceName& name, bool delay_unsubscription)
181
182
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
182
183
 
183
184
  bool HasSubscribedResources() const;
184
185
 
185
186
  private:
186
- class ResourceState : public InternallyRefCounted<ResourceState> {
187
+ class AdsResponseParser : public XdsApi::AdsResponseParserInterface {
187
188
  public:
188
- ResourceState(const std::string& type_url, const XdsApi::ResourceName& name)
189
- : type_url_(type_url), name_(name) {
189
+ struct Result {
190
+ const XdsResourceType* type;
191
+ std::string type_url;
192
+ std::string version;
193
+ std::string nonce;
194
+ std::vector<std::string> errors;
195
+ std::map<std::string /*authority*/, std::set<XdsResourceKey>>
196
+ resources_seen;
197
+ bool have_valid_resources = false;
198
+ };
199
+
200
+ explicit AdsResponseParser(AdsCallState* ads_call_state)
201
+ : ads_call_state_(ads_call_state) {}
202
+
203
+ absl::Status ProcessAdsResponseFields(AdsResponseFields fields) override
204
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
205
+
206
+ void ParseResource(const XdsEncodingContext& context, size_t idx,
207
+ absl::string_view type_url,
208
+ absl::string_view serialized_resource) override
209
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
210
+
211
+ Result TakeResult() { return std::move(result_); }
212
+
213
+ private:
214
+ XdsClient* xds_client() const { return ads_call_state_->xds_client(); }
215
+
216
+ AdsCallState* ads_call_state_;
217
+ const grpc_millis update_time_ = ExecCtx::Get()->Now();
218
+ Result result_;
219
+ };
220
+
221
+ class ResourceTimer : public InternallyRefCounted<ResourceTimer> {
222
+ public:
223
+ ResourceTimer(const XdsResourceType* type, const XdsResourceName& name)
224
+ : type_(type), name_(name) {
190
225
  GRPC_CLOSURE_INIT(&timer_callback_, OnTimer, this,
191
226
  grpc_schedule_on_exec_ctx);
192
227
  }
@@ -217,7 +252,7 @@ class XdsClient::ChannelState::AdsCallState
217
252
 
218
253
  private:
219
254
  static void OnTimer(void* arg, grpc_error_handle error) {
220
- ResourceState* self = static_cast<ResourceState*>(arg);
255
+ ResourceTimer* self = static_cast<ResourceTimer*>(arg);
221
256
  {
222
257
  MutexLock lock(&self->ads_calld_->xds_client()->mu_);
223
258
  self->OnTimerLocked(GRPC_ERROR_REF(error));
@@ -234,51 +269,30 @@ class XdsClient::ChannelState::AdsCallState
234
269
  grpc_error_handle watcher_error =
235
270
  GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrFormat(
236
271
  "timeout obtaining resource {type=%s name=%s} from xds server",
237
- type_url_,
238
- XdsApi::ConstructFullResourceName(name_.authority, type_url_,
239
- name_.id)));
272
+ type_->type_url(),
273
+ XdsClient::ConstructFullXdsResourceName(
274
+ name_.authority, type_->type_url(), name_.key)));
240
275
  watcher_error = grpc_error_set_int(
241
276
  watcher_error, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
242
277
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
243
- gpr_log(GPR_INFO, "[xds_client %p] %s", ads_calld_->xds_client(),
278
+ gpr_log(GPR_INFO, "[xds_client %p] xds server %s: %s",
279
+ ads_calld_->xds_client(),
280
+ ads_calld_->chand()->server_.server_uri.c_str(),
244
281
  grpc_error_std_string(watcher_error).c_str());
245
282
  }
246
283
  auto& authority_state =
247
284
  ads_calld_->xds_client()->authority_state_map_[name_.authority];
248
- if (type_url_ == XdsApi::kLdsTypeUrl) {
249
- ListenerState& state = authority_state.listener_map[name_.id];
250
- state.meta.client_status = XdsApi::ResourceMetadata::DOES_NOT_EXIST;
251
- Notifier::ScheduleNotifyWatchersOnErrorInWorkSerializer(
252
- ads_calld_->xds_client(), state.watchers,
253
- GRPC_ERROR_REF(watcher_error), DEBUG_LOCATION);
254
- } else if (type_url_ == XdsApi::kRdsTypeUrl) {
255
- RouteConfigState& state = authority_state.route_config_map[name_.id];
256
- state.meta.client_status = XdsApi::ResourceMetadata::DOES_NOT_EXIST;
257
- Notifier::ScheduleNotifyWatchersOnErrorInWorkSerializer(
258
- ads_calld_->xds_client(), state.watchers,
259
- GRPC_ERROR_REF(watcher_error), DEBUG_LOCATION);
260
- } else if (type_url_ == XdsApi::kCdsTypeUrl) {
261
- ClusterState& state = authority_state.cluster_map[name_.id];
262
- state.meta.client_status = XdsApi::ResourceMetadata::DOES_NOT_EXIST;
263
- Notifier::ScheduleNotifyWatchersOnErrorInWorkSerializer(
264
- ads_calld_->xds_client(), state.watchers,
265
- GRPC_ERROR_REF(watcher_error), DEBUG_LOCATION);
266
- } else if (type_url_ == XdsApi::kEdsTypeUrl) {
267
- EndpointState& state = authority_state.endpoint_map[name_.id];
268
- state.meta.client_status = XdsApi::ResourceMetadata::DOES_NOT_EXIST;
269
- Notifier::ScheduleNotifyWatchersOnErrorInWorkSerializer(
270
- ads_calld_->xds_client(), state.watchers,
271
- GRPC_ERROR_REF(watcher_error), DEBUG_LOCATION);
272
- } else {
273
- GPR_UNREACHABLE_CODE(return );
274
- }
275
- GRPC_ERROR_UNREF(watcher_error);
285
+ ResourceState& state = authority_state.resource_map[type_][name_.key];
286
+ state.meta.client_status = XdsApi::ResourceMetadata::DOES_NOT_EXIST;
287
+ Notifier::ScheduleNotifyWatchersOnErrorInWorkSerializer(
288
+ ads_calld_->xds_client(), state.watchers, watcher_error,
289
+ DEBUG_LOCATION);
276
290
  }
277
291
  GRPC_ERROR_UNREF(error);
278
292
  }
279
293
 
280
- const std::string type_url_;
281
- const XdsApi::ResourceName name_;
294
+ const XdsResourceType* type_;
295
+ const XdsResourceName name_;
282
296
 
283
297
  RefCountedPtr<AdsCallState> ads_calld_;
284
298
  bool timer_started_ = false;
@@ -296,40 +310,11 @@ class XdsClient::ChannelState::AdsCallState
296
310
 
297
311
  // Subscribed resources of this type.
298
312
  std::map<std::string /*authority*/,
299
- std::map<std::string /*name*/, OrphanablePtr<ResourceState>>>
313
+ std::map<XdsResourceKey, OrphanablePtr<ResourceTimer>>>
300
314
  subscribed_resources;
301
315
  };
302
316
 
303
- void SendMessageLocked(const std::string& type_url)
304
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
305
-
306
- void AcceptLdsUpdateLocked(
307
- std::string version, grpc_millis update_time,
308
- XdsApi::LdsUpdateMap lds_update_map,
309
- const std::set<XdsApi::ResourceName>& resource_names_failed)
310
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
311
- void AcceptRdsUpdateLocked(std::string version, grpc_millis update_time,
312
- XdsApi::RdsUpdateMap rds_update_map)
313
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
314
- void AcceptCdsUpdateLocked(
315
- std::string version, grpc_millis update_time,
316
- XdsApi::CdsUpdateMap cds_update_map,
317
- const std::set<XdsApi::ResourceName>& resource_names_failed)
318
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
319
- void AcceptEdsUpdateLocked(std::string version, grpc_millis update_time,
320
- XdsApi::EdsUpdateMap eds_update_map)
321
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
322
-
323
- template <typename StateMap>
324
- void RejectAdsUpdateHelperLocked(const std::string& resource_name,
325
- grpc_millis update_time,
326
- const XdsApi::AdsParseResult& result,
327
- const std::string& error_details,
328
- StateMap* state_map)
329
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
330
-
331
- void RejectAdsUpdateLocked(grpc_millis update_time,
332
- const XdsApi::AdsParseResult& result)
317
+ void SendMessageLocked(const XdsResourceType* type)
333
318
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
334
319
 
335
320
  static void OnRequestSent(void* arg, grpc_error_handle error);
@@ -344,9 +329,9 @@ class XdsClient::ChannelState::AdsCallState
344
329
 
345
330
  bool IsCurrentCallOnChannel() const;
346
331
 
347
- std::map<absl::string_view /*authority*/,
348
- std::set<absl::string_view /*name*/>>
349
- ResourceNamesForRequest(const std::string& type_url);
332
+ // Constructs a list of resource names of a given type for an ADS
333
+ // request. Also starts the timer for each resource if needed.
334
+ std::vector<std::string> ResourceNamesForRequest(const XdsResourceType* type);
350
335
 
351
336
  // The owning RetryableCall<>.
352
337
  RefCountedPtr<RetryableCall<AdsCallState>> parent_;
@@ -375,10 +360,10 @@ class XdsClient::ChannelState::AdsCallState
375
360
  grpc_closure on_status_received_;
376
361
 
377
362
  // Resource types for which requests need to be sent.
378
- std::set<std::string /*type_url*/> buffered_requests_;
363
+ std::set<const XdsResourceType*> buffered_requests_;
379
364
 
380
365
  // State for each resource type.
381
- std::map<std::string /*type_url*/, ResourceTypeState> state_map_;
366
+ std::map<const XdsResourceType*, ResourceTypeState> state_map_;
382
367
  };
383
368
 
384
369
  // Contains an LRS call to the xds server.
@@ -503,9 +488,10 @@ class XdsClient::ChannelState::StateWatcher
503
488
  new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
504
489
  // In TRANSIENT_FAILURE. Notify all watchers of error.
505
490
  gpr_log(GPR_INFO,
506
- "[xds_client %p] xds channel in state:TRANSIENT_FAILURE "
507
- "status_message:(%s)",
508
- parent_->xds_client(), status.ToString().c_str());
491
+ "[xds_client %p] xds channel for server %s in "
492
+ "state TRANSIENT_FAILURE: %s",
493
+ parent_->xds_client(), parent_->server_.server_uri.c_str(),
494
+ status.ToString().c_str());
509
495
  parent_->xds_client_->NotifyOnErrorLocked(
510
496
  GRPC_ERROR_CREATE_FROM_STATIC_STRING(
511
497
  "xds channel in TRANSIENT_FAILURE"));
@@ -526,8 +512,8 @@ namespace {
526
512
  grpc_channel* CreateXdsChannel(grpc_channel_args* args,
527
513
  const XdsBootstrap::XdsServer& server) {
528
514
  RefCountedPtr<grpc_channel_credentials> channel_creds =
529
- XdsChannelCredsRegistry::MakeChannelCreds(server.channel_creds_type,
530
- server.channel_creds_config);
515
+ XdsChannelCredsRegistry::CreateXdsChannelCreds(
516
+ server.channel_creds_type, server.channel_creds_config);
531
517
  return grpc_secure_channel_create(channel_creds.get(),
532
518
  server.server_uri.c_str(), args, nullptr);
533
519
  }
@@ -553,8 +539,8 @@ XdsClient::ChannelState::ChannelState(WeakRefCountedPtr<XdsClient> xds_client,
553
539
 
554
540
  XdsClient::ChannelState::~ChannelState() {
555
541
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
556
- gpr_log(GPR_INFO, "[xds_client %p] Destroying xds channel %p", xds_client(),
557
- this);
542
+ gpr_log(GPR_INFO, "[xds_client %p] destroying xds channel %p for server %s",
543
+ xds_client(), this, server_.server_uri.c_str());
558
544
  }
559
545
  grpc_channel_destroy(channel_);
560
546
  xds_client_.reset(DEBUG_LOCATION, "ChannelState");
@@ -612,8 +598,8 @@ void XdsClient::ChannelState::CancelConnectivityWatchLocked() {
612
598
  client_channel->RemoveConnectivityWatcher(watcher_);
613
599
  }
614
600
 
615
- void XdsClient::ChannelState::SubscribeLocked(
616
- const std::string& type_url, const XdsApi::ResourceName& name) {
601
+ void XdsClient::ChannelState::SubscribeLocked(const XdsResourceType* type,
602
+ const XdsResourceName& name) {
617
603
  if (ads_calld_ == nullptr) {
618
604
  // Start the ADS call if this is the first request.
619
605
  ads_calld_.reset(new RetryableCall<AdsCallState>(
@@ -627,16 +613,16 @@ void XdsClient::ChannelState::SubscribeLocked(
627
613
  // because when the call is restarted it will resend all necessary requests.
628
614
  if (ads_calld() == nullptr) return;
629
615
  // Subscribe to this resource if the ADS call is active.
630
- ads_calld()->SubscribeLocked(type_url, name);
616
+ ads_calld()->SubscribeLocked(type, name);
631
617
  }
632
618
 
633
- void XdsClient::ChannelState::UnsubscribeLocked(
634
- const std::string& type_url, const XdsApi::ResourceName& name,
635
- bool delay_unsubscription) {
619
+ void XdsClient::ChannelState::UnsubscribeLocked(const XdsResourceType* type,
620
+ const XdsResourceName& name,
621
+ bool delay_unsubscription) {
636
622
  if (ads_calld_ != nullptr) {
637
623
  auto* calld = ads_calld_->calld();
638
624
  if (calld != nullptr) {
639
- calld->UnsubscribeLocked(type_url, name, delay_unsubscription);
625
+ calld->UnsubscribeLocked(type, name, delay_unsubscription);
640
626
  if (!calld->HasSubscribedResources()) {
641
627
  ads_calld_.reset();
642
628
  }
@@ -694,10 +680,10 @@ void XdsClient::ChannelState::RetryableCall<T>::StartNewCallLocked() {
694
680
  GPR_ASSERT(chand_->channel_ != nullptr);
695
681
  GPR_ASSERT(calld_ == nullptr);
696
682
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
697
- gpr_log(GPR_INFO,
698
- "[xds_client %p] Start new call from retryable call (chand: %p, "
699
- "retryable call: %p)",
700
- chand()->xds_client(), chand(), this);
683
+ gpr_log(
684
+ GPR_INFO,
685
+ "[xds_client %p] xds server %s: start new call from retryable call %p",
686
+ chand()->xds_client(), chand()->server_.server_uri.c_str(), this);
701
687
  }
702
688
  calld_ = MakeOrphanable<T>(
703
689
  this->Ref(DEBUG_LOCATION, "RetryableCall+start_new_call"));
@@ -711,9 +697,10 @@ void XdsClient::ChannelState::RetryableCall<T>::StartRetryTimerLocked() {
711
697
  grpc_millis timeout =
712
698
  std::max(next_attempt_time - ExecCtx::Get()->Now(), grpc_millis(0));
713
699
  gpr_log(GPR_INFO,
714
- "[xds_client %p] Failed to connect to xds server (chand: %p) "
700
+ "[xds_client %p] xds server %s: call attempt failed; "
715
701
  "retry timer will fire in %" PRId64 "ms.",
716
- chand()->xds_client(), chand(), timeout);
702
+ chand()->xds_client(), chand()->server_.server_uri.c_str(),
703
+ timeout);
717
704
  }
718
705
  this->Ref(DEBUG_LOCATION, "RetryableCall+retry_timer_start").release();
719
706
  grpc_timer_init(&retry_timer_, next_attempt_time, &on_retry_timer_);
@@ -737,16 +724,183 @@ void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimerLocked(
737
724
  retry_timer_callback_pending_ = false;
738
725
  if (!shutting_down_ && error == GRPC_ERROR_NONE) {
739
726
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
740
- gpr_log(
741
- GPR_INFO,
742
- "[xds_client %p] Retry timer fires (chand: %p, retryable call: %p)",
743
- chand()->xds_client(), chand(), this);
727
+ gpr_log(GPR_INFO,
728
+ "[xds_client %p] xds server %s: retry timer fired (retryable "
729
+ "call: %p)",
730
+ chand()->xds_client(), chand()->server_.server_uri.c_str(), this);
744
731
  }
745
732
  StartNewCallLocked();
746
733
  }
747
734
  GRPC_ERROR_UNREF(error);
748
735
  }
749
736
 
737
+ //
738
+ // XdsClient::ChannelState::AdsCallState::AdsResponseParser
739
+ //
740
+
741
+ absl::Status XdsClient::ChannelState::AdsCallState::AdsResponseParser::
742
+ ProcessAdsResponseFields(AdsResponseFields fields) {
743
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
744
+ gpr_log(
745
+ GPR_INFO,
746
+ "[xds_client %p] xds server %s: received ADS response: type_url=%s, "
747
+ "version=%s, nonce=%s, num_resources=%" PRIuPTR,
748
+ ads_call_state_->xds_client(),
749
+ ads_call_state_->chand()->server_.server_uri.c_str(),
750
+ fields.type_url.c_str(), fields.version.c_str(), fields.nonce.c_str(),
751
+ fields.num_resources);
752
+ }
753
+ result_.type =
754
+ ads_call_state_->xds_client()->GetResourceTypeLocked(fields.type_url);
755
+ if (result_.type == nullptr) {
756
+ return absl::InvalidArgumentError(
757
+ absl::StrCat("unknown resource type ", fields.type_url));
758
+ }
759
+ result_.type_url = std::move(fields.type_url);
760
+ result_.version = std::move(fields.version);
761
+ result_.nonce = std::move(fields.nonce);
762
+ return absl::OkStatus();
763
+ }
764
+
765
+ namespace {
766
+
767
+ // Build a resource metadata struct for ADS result accepting methods and CSDS.
768
+ XdsApi::ResourceMetadata CreateResourceMetadataAcked(
769
+ std::string serialized_proto, std::string version,
770
+ grpc_millis update_time) {
771
+ XdsApi::ResourceMetadata resource_metadata;
772
+ resource_metadata.serialized_proto = std::move(serialized_proto);
773
+ resource_metadata.update_time = update_time;
774
+ resource_metadata.version = std::move(version);
775
+ resource_metadata.client_status = XdsApi::ResourceMetadata::ACKED;
776
+ return resource_metadata;
777
+ }
778
+
779
+ // Update resource_metadata for NACK.
780
+ void UpdateResourceMetadataNacked(const std::string& version,
781
+ const std::string& details,
782
+ grpc_millis update_time,
783
+ XdsApi::ResourceMetadata* resource_metadata) {
784
+ resource_metadata->client_status = XdsApi::ResourceMetadata::NACKED;
785
+ resource_metadata->failed_version = version;
786
+ resource_metadata->failed_details = details;
787
+ resource_metadata->failed_update_time = update_time;
788
+ }
789
+
790
+ } // namespace
791
+
792
+ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
793
+ const XdsEncodingContext& context, size_t idx, absl::string_view type_url,
794
+ absl::string_view serialized_resource) {
795
+ // Check the type_url of the resource.
796
+ bool is_v2 = false;
797
+ if (!result_.type->IsType(type_url, &is_v2)) {
798
+ result_.errors.emplace_back(
799
+ absl::StrCat("resource index ", idx, ": incorrect resource type ",
800
+ type_url, " (should be ", result_.type_url, ")"));
801
+ return;
802
+ }
803
+ // Parse the resource.
804
+ absl::StatusOr<XdsResourceType::DecodeResult> result =
805
+ result_.type->Decode(context, serialized_resource, is_v2);
806
+ if (!result.ok()) {
807
+ result_.errors.emplace_back(
808
+ absl::StrCat("resource index ", idx, ": ", result.status().ToString()));
809
+ return;
810
+ }
811
+ // Check the resource name.
812
+ auto resource_name =
813
+ XdsClient::ParseXdsResourceName(result->name, result_.type);
814
+ if (!resource_name.ok()) {
815
+ result_.errors.emplace_back(absl::StrCat(
816
+ "resource index ", idx, ": Cannot parse xDS resource name \"",
817
+ result->name, "\""));
818
+ return;
819
+ }
820
+ // Cancel resource-does-not-exist timer, if needed.
821
+ auto timer_it = ads_call_state_->state_map_.find(result_.type);
822
+ if (timer_it != ads_call_state_->state_map_.end()) {
823
+ auto it =
824
+ timer_it->second.subscribed_resources.find(resource_name->authority);
825
+ if (it != timer_it->second.subscribed_resources.end()) {
826
+ auto res_it = it->second.find(resource_name->key);
827
+ if (res_it != it->second.end()) {
828
+ res_it->second->MaybeCancelTimer();
829
+ }
830
+ }
831
+ }
832
+ // Lookup the authority in the cache.
833
+ auto authority_it =
834
+ xds_client()->authority_state_map_.find(resource_name->authority);
835
+ if (authority_it == xds_client()->authority_state_map_.end()) {
836
+ return; // Skip resource -- we don't have a subscription for it.
837
+ }
838
+ // Found authority, so look up type.
839
+ AuthorityState& authority_state = authority_it->second;
840
+ auto type_it = authority_state.resource_map.find(result_.type);
841
+ if (type_it == authority_state.resource_map.end()) {
842
+ return; // Skip resource -- we don't have a subscription for it.
843
+ }
844
+ auto& type_map = type_it->second;
845
+ // Found type, so look up resource key.
846
+ auto it = type_map.find(resource_name->key);
847
+ if (it == type_map.end()) {
848
+ return; // Skip resource -- we don't have a subscription for it.
849
+ }
850
+ ResourceState& resource_state = it->second;
851
+ // If needed, record that we've seen this resource.
852
+ if (result_.type->AllResourcesRequiredInSotW()) {
853
+ result_.resources_seen[resource_name->authority].insert(resource_name->key);
854
+ }
855
+ // Update resource state based on whether the resource is valid.
856
+ if (!result->resource.ok()) {
857
+ result_.errors.emplace_back(absl::StrCat(
858
+ "resource index ", idx, ": ", result->name,
859
+ ": validation error: ", result->resource.status().ToString()));
860
+ Notifier::ScheduleNotifyWatchersOnErrorInWorkSerializer(
861
+ xds_client(), resource_state.watchers,
862
+ grpc_error_set_int(
863
+ GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
864
+ "invalid resource: ", result->resource.status().ToString())),
865
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
866
+ DEBUG_LOCATION);
867
+ UpdateResourceMetadataNacked(result_.version,
868
+ result->resource.status().ToString(),
869
+ update_time_, &resource_state.meta);
870
+ return;
871
+ }
872
+ // Resource is valid.
873
+ result_.have_valid_resources = true;
874
+ // If it didn't change, ignore it.
875
+ if (resource_state.resource != nullptr &&
876
+ result_.type->ResourcesEqual(resource_state.resource.get(),
877
+ result->resource->get())) {
878
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
879
+ gpr_log(GPR_INFO,
880
+ "[xds_client %p] %s resource %s identical to current, ignoring.",
881
+ xds_client(), result_.type_url.c_str(), result->name.c_str());
882
+ }
883
+ return;
884
+ }
885
+ // Update the resource state.
886
+ resource_state.resource = std::move(*result->resource);
887
+ resource_state.meta = CreateResourceMetadataAcked(
888
+ std::string(serialized_resource), result_.version, update_time_);
889
+ // Notify watchers.
890
+ auto& watchers_list = resource_state.watchers;
891
+ auto* value =
892
+ result_.type->CopyResource(resource_state.resource.get()).release();
893
+ xds_client()->work_serializer_.Schedule(
894
+ [watchers_list, value]()
895
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&xds_client()->work_serializer_) {
896
+ for (const auto& p : watchers_list) {
897
+ p.first->OnGenericResourceChanged(value);
898
+ }
899
+ delete value;
900
+ },
901
+ DEBUG_LOCATION);
902
+ }
903
+
750
904
  //
751
905
  // XdsClient::ChannelState::AdsCallState
752
906
  //
@@ -763,13 +917,16 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
763
917
  // the polling entities from client_channel.
764
918
  GPR_ASSERT(xds_client() != nullptr);
765
919
  // Create a call with the specified method name.
766
- const auto& method =
920
+ const char* method =
767
921
  chand()->server_.ShouldUseV3()
768
- ? GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V3_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES
769
- : GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V2_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES;
922
+ ? "/envoy.service.discovery.v3.AggregatedDiscoveryService/"
923
+ "StreamAggregatedResources"
924
+ : "/envoy.service.discovery.v2.AggregatedDiscoveryService/"
925
+ "StreamAggregatedResources";
770
926
  call_ = grpc_channel_create_pollset_set_call(
771
927
  chand()->channel_, nullptr, GRPC_PROPAGATE_DEFAULTS,
772
- xds_client()->interested_parties_, method, nullptr,
928
+ xds_client()->interested_parties_,
929
+ StaticSlice::FromStaticString(method).c_slice(), nullptr,
773
930
  GRPC_MILLIS_INF_FUTURE, nullptr);
774
931
  GPR_ASSERT(call_ != nullptr);
775
932
  // Init data associated with the call.
@@ -778,9 +935,9 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
778
935
  // Start the call.
779
936
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
780
937
  gpr_log(GPR_INFO,
781
- "[xds_client %p] Starting ADS call (chand: %p, calld: %p, "
782
- "call: %p)",
783
- xds_client(), chand(), this, call_);
938
+ "[xds_client %p] xds server %s: starting ADS call "
939
+ "(calld: %p, call: %p)",
940
+ xds_client(), chand()->server_.server_uri.c_str(), this, call_);
784
941
  }
785
942
  // Create the ops.
786
943
  grpc_call_error call_error;
@@ -804,21 +961,12 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
804
961
  const std::string& authority = a.first;
805
962
  // Skip authorities that are not using this xDS channel.
806
963
  if (a.second.channel_state != chand()) continue;
807
- for (const auto& l : a.second.listener_map) {
808
- const std::string& listener_name = l.first;
809
- SubscribeLocked(XdsApi::kLdsTypeUrl, {authority, listener_name});
810
- }
811
- for (const auto& r : a.second.route_config_map) {
812
- const std::string& route_config_name = r.first;
813
- SubscribeLocked(XdsApi::kRdsTypeUrl, {authority, route_config_name});
814
- }
815
- for (const auto& c : a.second.cluster_map) {
816
- const std::string& cluster_name = c.first;
817
- SubscribeLocked(XdsApi::kCdsTypeUrl, {authority, cluster_name});
818
- }
819
- for (const auto& e : a.second.endpoint_map) {
820
- const std::string& endpoint_name = e.first;
821
- SubscribeLocked(XdsApi::kEdsTypeUrl, {authority, endpoint_name});
964
+ for (const auto& t : a.second.resource_map) {
965
+ const XdsResourceType* type = t.first;
966
+ for (const auto& r : t.second) {
967
+ const XdsResourceKey& resource_key = r.first;
968
+ SubscribeLocked(type, {authority, resource_key});
969
+ }
822
970
  }
823
971
  }
824
972
  // Op: recv initial metadata.
@@ -883,33 +1031,29 @@ void XdsClient::ChannelState::AdsCallState::Orphan() {
883
1031
  }
884
1032
 
885
1033
  void XdsClient::ChannelState::AdsCallState::SendMessageLocked(
886
- const std::string& type_url)
1034
+ const XdsResourceType* type)
887
1035
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_) {
888
1036
  // Buffer message sending if an existing message is in flight.
889
1037
  if (send_message_payload_ != nullptr) {
890
- buffered_requests_.insert(type_url);
1038
+ buffered_requests_.insert(type);
891
1039
  return;
892
1040
  }
893
- auto& state = state_map_[type_url];
1041
+ auto& state = state_map_[type];
894
1042
  grpc_slice request_payload_slice;
895
- std::map<absl::string_view /*authority*/,
896
- std::set<absl::string_view /*name*/>>
897
- resource_map = ResourceNamesForRequest(type_url);
898
1043
  request_payload_slice = xds_client()->api_.CreateAdsRequest(
899
- chand()->server_, type_url, resource_map,
900
- chand()->resource_type_version_map_[type_url], state.nonce,
901
- GRPC_ERROR_REF(state.error), !sent_initial_message_);
902
- if (type_url != XdsApi::kLdsTypeUrl && type_url != XdsApi::kRdsTypeUrl &&
903
- type_url != XdsApi::kCdsTypeUrl && type_url != XdsApi::kEdsTypeUrl) {
904
- state_map_.erase(type_url);
905
- }
1044
+ chand()->server_,
1045
+ chand()->server_.ShouldUseV3() ? type->type_url() : type->v2_type_url(),
1046
+ chand()->resource_type_version_map_[type], state.nonce,
1047
+ ResourceNamesForRequest(type), GRPC_ERROR_REF(state.error),
1048
+ !sent_initial_message_);
906
1049
  sent_initial_message_ = true;
907
1050
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
908
1051
  gpr_log(GPR_INFO,
909
- "[xds_client %p] sending ADS request: type=%s version=%s nonce=%s "
910
- "error=%s",
911
- xds_client(), type_url.c_str(),
912
- chand()->resource_type_version_map_[type_url].c_str(),
1052
+ "[xds_client %p] xds server %s: sending ADS request: type=%s "
1053
+ "version=%s nonce=%s error=%s",
1054
+ xds_client(), chand()->server_.server_uri.c_str(),
1055
+ std::string(type->type_url()).c_str(),
1056
+ chand()->resource_type_version_map_[type].c_str(),
913
1057
  state.nonce.c_str(), grpc_error_std_string(state.error).c_str());
914
1058
  }
915
1059
  GRPC_ERROR_UNREF(state.error);
@@ -930,32 +1074,33 @@ void XdsClient::ChannelState::AdsCallState::SendMessageLocked(
930
1074
  grpc_call_start_batch_and_execute(call_, &op, 1, &on_request_sent_);
931
1075
  if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) {
932
1076
  gpr_log(GPR_ERROR,
933
- "[xds_client %p] calld=%p call_error=%d sending ADS message",
934
- xds_client(), this, call_error);
1077
+ "[xds_client %p] xds server %s: error starting ADS send_message "
1078
+ "batch on calld=%p: call_error=%d",
1079
+ xds_client(), chand()->server_.server_uri.c_str(), this,
1080
+ call_error);
935
1081
  GPR_ASSERT(GRPC_CALL_OK == call_error);
936
1082
  }
937
1083
  }
938
1084
 
939
1085
  void XdsClient::ChannelState::AdsCallState::SubscribeLocked(
940
- const std::string& type_url, const XdsApi::ResourceName& name) {
941
- auto& state =
942
- state_map_[type_url].subscribed_resources[name.authority][name.id];
1086
+ const XdsResourceType* type, const XdsResourceName& name) {
1087
+ auto& state = state_map_[type].subscribed_resources[name.authority][name.key];
943
1088
  if (state == nullptr) {
944
- state = MakeOrphanable<ResourceState>(type_url, name);
945
- SendMessageLocked(type_url);
1089
+ state = MakeOrphanable<ResourceTimer>(type, name);
1090
+ SendMessageLocked(type);
946
1091
  }
947
1092
  }
948
1093
 
949
1094
  void XdsClient::ChannelState::AdsCallState::UnsubscribeLocked(
950
- const std::string& type_url, const XdsApi::ResourceName& name,
1095
+ const XdsResourceType* type, const XdsResourceName& name,
951
1096
  bool delay_unsubscription) {
952
- auto& type_state_map = state_map_[type_url];
1097
+ auto& type_state_map = state_map_[type];
953
1098
  auto& authority_map = type_state_map.subscribed_resources[name.authority];
954
- authority_map.erase(name.id);
1099
+ authority_map.erase(name.key);
955
1100
  if (authority_map.empty()) {
956
1101
  type_state_map.subscribed_resources.erase(name.authority);
957
1102
  }
958
- if (!delay_unsubscription) SendMessageLocked(type_url);
1103
+ if (!delay_unsubscription) SendMessageLocked(type);
959
1104
  }
960
1105
 
961
1106
  bool XdsClient::ChannelState::AdsCallState::HasSubscribedResources() const {
@@ -965,395 +1110,6 @@ bool XdsClient::ChannelState::AdsCallState::HasSubscribedResources() const {
965
1110
  return false;
966
1111
  }
967
1112
 
968
- namespace {
969
-
970
- // Build a resource metadata struct for ADS result accepting methods and CSDS.
971
- XdsApi::ResourceMetadata CreateResourceMetadataAcked(
972
- std::string serialized_proto, std::string version,
973
- grpc_millis update_time) {
974
- XdsApi::ResourceMetadata resource_metadata;
975
- resource_metadata.serialized_proto = std::move(serialized_proto);
976
- resource_metadata.update_time = update_time;
977
- resource_metadata.version = std::move(version);
978
- resource_metadata.client_status = XdsApi::ResourceMetadata::ACKED;
979
- return resource_metadata;
980
- }
981
-
982
- } // namespace
983
-
984
- void XdsClient::ChannelState::AdsCallState::AcceptLdsUpdateLocked(
985
- std::string version, grpc_millis update_time,
986
- XdsApi::LdsUpdateMap lds_update_map,
987
- const std::set<XdsApi::ResourceName>& resource_names_failed) {
988
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
989
- gpr_log(GPR_INFO,
990
- "[xds_client %p] LDS update received containing %" PRIuPTR
991
- " resources",
992
- xds_client(), lds_update_map.size());
993
- }
994
- auto& lds_state = state_map_[XdsApi::kLdsTypeUrl];
995
- for (auto& p : lds_update_map) {
996
- const XdsApi::ResourceName& name = p.first;
997
- XdsApi::LdsUpdate& lds_update = p.second.resource;
998
- auto it = lds_state.subscribed_resources.find(name.authority);
999
- if (it != lds_state.subscribed_resources.end()) {
1000
- auto res_it = it->second.find(name.id);
1001
- if (res_it != it->second.end()) {
1002
- res_it->second->MaybeCancelTimer();
1003
- }
1004
- }
1005
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1006
- gpr_log(GPR_INFO, "[xds_client %p] LDS resource %s: %s", xds_client(),
1007
- XdsApi::ConstructFullResourceName(name.authority,
1008
- XdsApi::kLdsTypeUrl, name.id)
1009
- .c_str(),
1010
- lds_update.ToString().c_str());
1011
- }
1012
- ListenerState& listener_state = xds_client()
1013
- ->authority_state_map_[name.authority]
1014
- .listener_map[name.id];
1015
- // Ignore identical update.
1016
- if (listener_state.update.has_value() &&
1017
- *listener_state.update == lds_update) {
1018
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1019
- gpr_log(GPR_INFO,
1020
- "[xds_client %p] LDS update for %s identical to current, "
1021
- "ignoring.",
1022
- xds_client(),
1023
- XdsApi::ConstructFullResourceName(name.authority,
1024
- XdsApi::kLdsTypeUrl, name.id)
1025
- .c_str());
1026
- }
1027
- continue;
1028
- }
1029
- // Update the listener state.
1030
- listener_state.update = std::move(lds_update);
1031
- listener_state.meta = CreateResourceMetadataAcked(
1032
- std::move(p.second.serialized_proto), version, update_time);
1033
- // Notify watchers.
1034
- auto& watchers_list = listener_state.watchers;
1035
- auto& value = listener_state.update.value();
1036
- xds_client()->work_serializer_.Schedule(
1037
- [watchers_list, value]()
1038
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&xds_client()->work_serializer_) {
1039
- for (const auto& p : watchers_list) {
1040
- p.first->OnListenerChanged(value);
1041
- }
1042
- },
1043
- DEBUG_LOCATION);
1044
- }
1045
- // For invalid resources in the update, if they are already in the
1046
- // cache, pretend that they are present in the update, so that we
1047
- // don't incorrectly consider them deleted below.
1048
- for (const auto& name : resource_names_failed) {
1049
- auto& listener_map =
1050
- xds_client()->authority_state_map_[name.authority].listener_map;
1051
- auto it = listener_map.find(name.id);
1052
- if (it != listener_map.end()) {
1053
- auto& update = it->second.update;
1054
- if (!update.has_value()) continue;
1055
- lds_update_map[name];
1056
- }
1057
- }
1058
- // For any subscribed resource that is not present in the update,
1059
- // remove it from the cache and notify watchers that it does not exist.
1060
- for (const auto& a : lds_state.subscribed_resources) {
1061
- const std::string& authority_name = a.first;
1062
- for (const auto& p : a.second) {
1063
- const std::string& listener_name = p.first;
1064
- if (lds_update_map.find({authority_name, listener_name}) ==
1065
- lds_update_map.end()) {
1066
- ListenerState& listener_state =
1067
- xds_client()
1068
- ->authority_state_map_[authority_name]
1069
- .listener_map[listener_name];
1070
- // If the resource was newly requested but has not yet been received,
1071
- // we don't want to generate an error for the watchers, because this LDS
1072
- // response may be in reaction to an earlier request that did not yet
1073
- // request the new resource, so its absence from the response does not
1074
- // necessarily indicate that the resource does not exist.
1075
- // For that case, we rely on the request timeout instead.
1076
- if (!listener_state.update.has_value()) continue;
1077
- listener_state.update.reset();
1078
- Notifier::ScheduleNotifyWatchersOnResourceDoesNotExistInWorkSerializer(
1079
- xds_client(), listener_state.watchers, DEBUG_LOCATION);
1080
- }
1081
- }
1082
- }
1083
- }
1084
-
1085
- void XdsClient::ChannelState::AdsCallState::AcceptRdsUpdateLocked(
1086
- std::string version, grpc_millis update_time,
1087
- XdsApi::RdsUpdateMap rds_update_map) {
1088
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1089
- gpr_log(GPR_INFO,
1090
- "[xds_client %p] RDS update received containing %" PRIuPTR
1091
- " resources",
1092
- xds_client(), rds_update_map.size());
1093
- }
1094
- auto& rds_state = state_map_[XdsApi::kRdsTypeUrl];
1095
- for (auto& p : rds_update_map) {
1096
- const XdsApi::ResourceName& name = p.first;
1097
- XdsApi::RdsUpdate& rds_update = p.second.resource;
1098
- auto it = rds_state.subscribed_resources.find(name.authority);
1099
- if (it != rds_state.subscribed_resources.end()) {
1100
- auto res_it = it->second.find(name.id);
1101
- if (res_it != it->second.end()) {
1102
- res_it->second->MaybeCancelTimer();
1103
- }
1104
- }
1105
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1106
- gpr_log(GPR_INFO, "[xds_client %p] RDS resource:\n%s", xds_client(),
1107
- rds_update.ToString().c_str());
1108
- }
1109
- RouteConfigState& route_config_state =
1110
- xds_client()
1111
- ->authority_state_map_[name.authority]
1112
- .route_config_map[name.id];
1113
- // Ignore identical update.
1114
- if (route_config_state.update.has_value() &&
1115
- *route_config_state.update == rds_update) {
1116
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1117
- gpr_log(GPR_INFO,
1118
- "[xds_client %p] RDS resource identical to current, ignoring",
1119
- xds_client());
1120
- }
1121
- continue;
1122
- }
1123
- // Update the cache.
1124
- route_config_state.update = std::move(rds_update);
1125
- route_config_state.meta = CreateResourceMetadataAcked(
1126
- std::move(p.second.serialized_proto), version, update_time);
1127
- // Notify all watchers.
1128
- auto& watchers_list = route_config_state.watchers;
1129
- auto& value = route_config_state.update.value();
1130
- xds_client()->work_serializer_.Schedule(
1131
- [watchers_list, value]()
1132
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&xds_client()->work_serializer_) {
1133
- for (const auto& p : watchers_list) {
1134
- p.first->OnRouteConfigChanged(value);
1135
- }
1136
- },
1137
- DEBUG_LOCATION);
1138
- }
1139
- }
1140
-
1141
- void XdsClient::ChannelState::AdsCallState::AcceptCdsUpdateLocked(
1142
- std::string version, grpc_millis update_time,
1143
- XdsApi::CdsUpdateMap cds_update_map,
1144
- const std::set<XdsApi::ResourceName>& resource_names_failed) {
1145
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1146
- gpr_log(GPR_INFO,
1147
- "[xds_client %p] CDS update received containing %" PRIuPTR
1148
- " resources",
1149
- xds_client(), cds_update_map.size());
1150
- }
1151
- auto& cds_state = state_map_[XdsApi::kCdsTypeUrl];
1152
- for (auto& p : cds_update_map) {
1153
- const XdsApi::ResourceName& name = p.first;
1154
- XdsApi::CdsUpdate& cds_update = p.second.resource;
1155
- auto it = cds_state.subscribed_resources.find(name.authority);
1156
- if (it != cds_state.subscribed_resources.end()) {
1157
- auto res_it = it->second.find(name.id);
1158
- if (res_it != it->second.end()) {
1159
- res_it->second->MaybeCancelTimer();
1160
- }
1161
- }
1162
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1163
- gpr_log(GPR_INFO, "[xds_client %p] cluster=%s: %s", xds_client(),
1164
- XdsApi::ConstructFullResourceName(name.authority,
1165
- XdsApi::kCdsTypeUrl, name.id)
1166
- .c_str(),
1167
- cds_update.ToString().c_str());
1168
- }
1169
- ClusterState& cluster_state =
1170
- xds_client()->authority_state_map_[name.authority].cluster_map[name.id];
1171
- // Ignore identical update.
1172
- if (cluster_state.update.has_value() &&
1173
- *cluster_state.update == cds_update) {
1174
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1175
- gpr_log(GPR_INFO,
1176
- "[xds_client %p] CDS update identical to current, ignoring.",
1177
- xds_client());
1178
- }
1179
- continue;
1180
- }
1181
- // Update the cluster state.
1182
- cluster_state.update = std::move(cds_update);
1183
- cluster_state.meta = CreateResourceMetadataAcked(
1184
- std::move(p.second.serialized_proto), version, update_time);
1185
- // Notify all watchers.
1186
- auto& watchers_list = cluster_state.watchers;
1187
- auto& value = cluster_state.update.value();
1188
- xds_client()->work_serializer_.Schedule(
1189
- [watchers_list, value]()
1190
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&xds_client()->work_serializer_) {
1191
- for (const auto& p : watchers_list) {
1192
- p.first->OnClusterChanged(value);
1193
- }
1194
- },
1195
- DEBUG_LOCATION);
1196
- }
1197
- // For invalid resources in the update, if they are already in the
1198
- // cache, pretend that they are present in the update, so that we
1199
- // don't incorrectly consider them deleted below.
1200
- for (const auto& name : resource_names_failed) {
1201
- auto& cluster_map =
1202
- xds_client()->authority_state_map_[name.authority].cluster_map;
1203
- auto it = cluster_map.find(name.id);
1204
- if (it != cluster_map.end()) {
1205
- auto& update = it->second.update;
1206
- if (!update.has_value()) continue;
1207
- cds_update_map[name];
1208
- }
1209
- }
1210
- // For any subscribed resource that is not present in the update,
1211
- // remove it from the cache and notify watchers that it does not exist.
1212
- for (const auto& a : cds_state.subscribed_resources) {
1213
- const std::string& authority = a.first;
1214
- for (const auto& p : a.second) {
1215
- const std::string& cluster_name = p.first;
1216
- if (cds_update_map.find({authority, cluster_name}) ==
1217
- cds_update_map.end()) {
1218
- ClusterState& cluster_state = xds_client()
1219
- ->authority_state_map_[authority]
1220
- .cluster_map[cluster_name];
1221
- // If the resource was newly requested but has not yet been received,
1222
- // we don't want to generate an error for the watchers, because this CDS
1223
- // response may be in reaction to an earlier request that did not yet
1224
- // request the new resource, so its absence from the response does not
1225
- // necessarily indicate that the resource does not exist.
1226
- // For that case, we rely on the request timeout instead.
1227
- if (!cluster_state.update.has_value()) continue;
1228
- cluster_state.update.reset();
1229
- Notifier::ScheduleNotifyWatchersOnResourceDoesNotExistInWorkSerializer(
1230
- xds_client(), cluster_state.watchers, DEBUG_LOCATION);
1231
- }
1232
- }
1233
- }
1234
- }
1235
-
1236
- void XdsClient::ChannelState::AdsCallState::AcceptEdsUpdateLocked(
1237
- std::string version, grpc_millis update_time,
1238
- XdsApi::EdsUpdateMap eds_update_map) {
1239
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1240
- gpr_log(GPR_INFO,
1241
- "[xds_client %p] EDS update received containing %" PRIuPTR
1242
- " resources",
1243
- xds_client(), eds_update_map.size());
1244
- }
1245
- auto& eds_state = state_map_[XdsApi::kEdsTypeUrl];
1246
- for (auto& p : eds_update_map) {
1247
- const XdsApi::ResourceName& name = p.first;
1248
- XdsApi::EdsUpdate& eds_update = p.second.resource;
1249
- auto it = eds_state.subscribed_resources.find(name.authority);
1250
- if (it != eds_state.subscribed_resources.end()) {
1251
- auto res_it = it->second.find(name.id);
1252
- if (res_it != it->second.end()) {
1253
- res_it->second->MaybeCancelTimer();
1254
- }
1255
- }
1256
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1257
- gpr_log(GPR_INFO, "[xds_client %p] EDS resource %s: %s", xds_client(),
1258
- XdsApi::ConstructFullResourceName(name.authority,
1259
- XdsApi::kCdsTypeUrl, name.id)
1260
- .c_str(),
1261
- eds_update.ToString().c_str());
1262
- }
1263
- EndpointState& endpoint_state = xds_client()
1264
- ->authority_state_map_[name.authority]
1265
- .endpoint_map[name.id];
1266
- // Ignore identical update.
1267
- if (endpoint_state.update.has_value() &&
1268
- *endpoint_state.update == eds_update) {
1269
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1270
- gpr_log(GPR_INFO,
1271
- "[xds_client %p] EDS update identical to current, ignoring.",
1272
- xds_client());
1273
- }
1274
- continue;
1275
- }
1276
- // Update the cluster state.
1277
- endpoint_state.update = std::move(eds_update);
1278
- endpoint_state.meta = CreateResourceMetadataAcked(
1279
- std::move(p.second.serialized_proto), version, update_time);
1280
- // Notify all watchers.
1281
- auto& watchers_list = endpoint_state.watchers;
1282
- auto& value = endpoint_state.update.value();
1283
- xds_client()->work_serializer_.Schedule(
1284
- [watchers_list, value]()
1285
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&xds_client()->work_serializer_) {
1286
- for (const auto& p : watchers_list) {
1287
- p.first->OnEndpointChanged(value);
1288
- }
1289
- },
1290
- DEBUG_LOCATION);
1291
- }
1292
- }
1293
-
1294
- namespace {
1295
-
1296
- // Update resource_metadata for NACK.
1297
- void UpdateResourceMetadataNacked(const std::string& version,
1298
- const std::string& details,
1299
- grpc_millis update_time,
1300
- XdsApi::ResourceMetadata* resource_metadata) {
1301
- resource_metadata->client_status = XdsApi::ResourceMetadata::NACKED;
1302
- resource_metadata->failed_version = version;
1303
- resource_metadata->failed_details = details;
1304
- resource_metadata->failed_update_time = update_time;
1305
- }
1306
-
1307
- } // namespace
1308
-
1309
- template <typename StateMap>
1310
- void XdsClient::ChannelState::AdsCallState::RejectAdsUpdateHelperLocked(
1311
- const std::string& resource_name, grpc_millis update_time,
1312
- const XdsApi::AdsParseResult& result, const std::string& error_details,
1313
- StateMap* state_map) {
1314
- auto it = state_map->find(resource_name);
1315
- if (it == state_map->end()) return;
1316
- auto& state = it->second;
1317
- Notifier::ScheduleNotifyWatchersOnErrorInWorkSerializer(
1318
- xds_client(), state.watchers, GRPC_ERROR_REF(result.parse_error),
1319
- DEBUG_LOCATION);
1320
- UpdateResourceMetadataNacked(result.version, error_details, update_time,
1321
- &state.meta);
1322
- }
1323
-
1324
- void XdsClient::ChannelState::AdsCallState::RejectAdsUpdateLocked(
1325
- grpc_millis update_time, const XdsApi::AdsParseResult& result) {
1326
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1327
- gpr_log(GPR_INFO,
1328
- "[xds_client %p] %s update NACKed containing %" PRIuPTR
1329
- " invalid resources",
1330
- xds_client(), result.type_url.c_str(),
1331
- result.resource_names_failed.size());
1332
- }
1333
- std::string details = grpc_error_std_string(result.parse_error);
1334
- for (auto& resource : result.resource_names_failed) {
1335
- auto authority_it =
1336
- xds_client()->authority_state_map_.find(resource.authority);
1337
- if (authority_it == xds_client()->authority_state_map_.end()) continue;
1338
- AuthorityState& authority_state = authority_it->second;
1339
- if (result.type_url == XdsApi::kLdsTypeUrl) {
1340
- RejectAdsUpdateHelperLocked(resource.id, update_time, result, details,
1341
- &authority_state.listener_map);
1342
- } else if (result.type_url == XdsApi::kRdsTypeUrl) {
1343
- RejectAdsUpdateHelperLocked(resource.id, update_time, result, details,
1344
- &authority_state.route_config_map);
1345
- } else if (result.type_url == XdsApi::kCdsTypeUrl) {
1346
- RejectAdsUpdateHelperLocked(resource.id, update_time, result, details,
1347
- &authority_state.cluster_map);
1348
- } else if (result.type_url == XdsApi::kEdsTypeUrl) {
1349
- RejectAdsUpdateHelperLocked(resource.id, update_time, result, details,
1350
- &authority_state.endpoint_map);
1351
- } else {
1352
- GPR_ASSERT(0);
1353
- }
1354
- }
1355
- }
1356
-
1357
1113
  void XdsClient::ChannelState::AdsCallState::OnRequestSent(
1358
1114
  void* arg, grpc_error_handle error) {
1359
1115
  AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
@@ -1413,63 +1169,76 @@ bool XdsClient::ChannelState::AdsCallState::OnResponseReceivedLocked() {
1413
1169
  grpc_byte_buffer_destroy(recv_message_payload_);
1414
1170
  recv_message_payload_ = nullptr;
1415
1171
  // Parse and validate the response.
1416
- XdsApi::AdsParseResult result = xds_client()->api_.ParseAdsResponse(
1417
- chand()->server_, response_slice,
1418
- ResourceNamesForRequest(XdsApi::kLdsTypeUrl),
1419
- ResourceNamesForRequest(XdsApi::kRdsTypeUrl),
1420
- ResourceNamesForRequest(XdsApi::kCdsTypeUrl),
1421
- ResourceNamesForRequest(XdsApi::kEdsTypeUrl));
1172
+ AdsResponseParser parser(this);
1173
+ absl::Status status = xds_client()->api_.ParseAdsResponse(
1174
+ chand()->server_, response_slice, &parser);
1422
1175
  grpc_slice_unref_internal(response_slice);
1423
- if (result.type_url.empty()) {
1176
+ if (!status.ok()) {
1424
1177
  // Ignore unparsable response.
1425
1178
  gpr_log(GPR_ERROR,
1426
- "[xds_client %p] Error parsing ADS response (%s) -- ignoring",
1427
- xds_client(), grpc_error_std_string(result.parse_error).c_str());
1428
- GRPC_ERROR_UNREF(result.parse_error);
1179
+ "[xds_client %p] xds server %s: error parsing ADS response (%s) "
1180
+ "-- ignoring",
1181
+ xds_client(), chand()->server_.server_uri.c_str(),
1182
+ status.ToString().c_str());
1429
1183
  } else {
1430
- grpc_millis update_time = ExecCtx::Get()->Now();
1184
+ AdsResponseParser::Result result = parser.TakeResult();
1431
1185
  // Update nonce.
1432
- auto& state = state_map_[result.type_url];
1433
- state.nonce = std::move(result.nonce);
1434
- // If we got an error, we'll NACK the update.
1435
- if (result.parse_error != GRPC_ERROR_NONE) {
1436
- gpr_log(GPR_ERROR,
1437
- "[xds_client %p] ADS response invalid for resource type %s "
1438
- "version %s, will NACK: nonce=%s error=%s",
1439
- xds_client(), result.type_url.c_str(), result.version.c_str(),
1440
- state.nonce.c_str(),
1441
- grpc_error_std_string(result.parse_error).c_str());
1442
- result.parse_error =
1443
- grpc_error_set_int(result.parse_error, GRPC_ERROR_INT_GRPC_STATUS,
1444
- GRPC_STATUS_UNAVAILABLE);
1186
+ auto& state = state_map_[result.type];
1187
+ state.nonce = result.nonce;
1188
+ // If we got an error, set state.error so that we'll NACK the update.
1189
+ if (!result.errors.empty()) {
1190
+ std::string error = absl::StrJoin(result.errors, "; ");
1191
+ gpr_log(
1192
+ GPR_ERROR,
1193
+ "[xds_client %p] xds server %s: ADS response invalid for resource "
1194
+ "type %s version %s, will NACK: nonce=%s error=%s",
1195
+ xds_client(), chand()->server_.server_uri.c_str(),
1196
+ result.type_url.c_str(), result.version.c_str(), state.nonce.c_str(),
1197
+ error.c_str());
1445
1198
  GRPC_ERROR_UNREF(state.error);
1446
- state.error = result.parse_error;
1447
- RejectAdsUpdateLocked(update_time, result);
1448
- }
1449
- // Process any valid resources.
1450
- bool have_valid_resources = false;
1451
- if (result.type_url == XdsApi::kLdsTypeUrl) {
1452
- have_valid_resources = !result.lds_update_map.empty();
1453
- AcceptLdsUpdateLocked(result.version, update_time,
1454
- std::move(result.lds_update_map),
1455
- result.resource_names_failed);
1456
- } else if (result.type_url == XdsApi::kRdsTypeUrl) {
1457
- have_valid_resources = !result.rds_update_map.empty();
1458
- AcceptRdsUpdateLocked(result.version, update_time,
1459
- std::move(result.rds_update_map));
1460
- } else if (result.type_url == XdsApi::kCdsTypeUrl) {
1461
- have_valid_resources = !result.cds_update_map.empty();
1462
- AcceptCdsUpdateLocked(result.version, update_time,
1463
- std::move(result.cds_update_map),
1464
- result.resource_names_failed);
1465
- } else if (result.type_url == XdsApi::kEdsTypeUrl) {
1466
- have_valid_resources = !result.eds_update_map.empty();
1467
- AcceptEdsUpdateLocked(result.version, update_time,
1468
- std::move(result.eds_update_map));
1199
+ state.error = grpc_error_set_int(
1200
+ GRPC_ERROR_CREATE_FROM_CPP_STRING(std::move(error)),
1201
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
1202
+ }
1203
+ // Delete resources not seen in update if needed.
1204
+ if (result.type->AllResourcesRequiredInSotW()) {
1205
+ for (auto& a : xds_client()->authority_state_map_) {
1206
+ const std::string& authority = a.first;
1207
+ AuthorityState& authority_state = a.second;
1208
+ // Skip authorities that are not using this xDS channel.
1209
+ if (authority_state.channel_state != chand()) continue;
1210
+ auto seen_authority_it = result.resources_seen.find(authority);
1211
+ // Find this resource type.
1212
+ auto type_it = authority_state.resource_map.find(result.type);
1213
+ if (type_it == authority_state.resource_map.end()) continue;
1214
+ // Iterate over resource ids.
1215
+ for (auto& r : type_it->second) {
1216
+ const XdsResourceKey& resource_key = r.first;
1217
+ ResourceState& resource_state = r.second;
1218
+ if (seen_authority_it == result.resources_seen.end() ||
1219
+ seen_authority_it->second.find(resource_key) ==
1220
+ seen_authority_it->second.end()) {
1221
+ // If the resource was newly requested but has not yet been
1222
+ // received, we don't want to generate an error for the watchers,
1223
+ // because this ADS response may be in reaction to an earlier
1224
+ // request that did not yet request the new resource, so its absence
1225
+ // from the response does not necessarily indicate that the resource
1226
+ // does not exist. For that case, we rely on the request timeout
1227
+ // instead.
1228
+ if (resource_state.resource == nullptr) continue;
1229
+ resource_state.resource.reset();
1230
+ Notifier::
1231
+ ScheduleNotifyWatchersOnResourceDoesNotExistInWorkSerializer(
1232
+ xds_client(), resource_state.watchers, DEBUG_LOCATION);
1233
+ }
1234
+ }
1235
+ }
1469
1236
  }
1470
- if (have_valid_resources) {
1237
+ // If we had valid resources, update the version.
1238
+ if (result.have_valid_resources) {
1471
1239
  seen_response_ = true;
1472
- chand()->resource_type_version_map_[result.type_url] = result.version;
1240
+ chand()->resource_type_version_map_[result.type] =
1241
+ std::move(result.version);
1473
1242
  // Start load reporting if needed.
1474
1243
  auto& lrs_call = chand()->lrs_calld_;
1475
1244
  if (lrs_call != nullptr) {
@@ -1478,7 +1247,7 @@ bool XdsClient::ChannelState::AdsCallState::OnResponseReceivedLocked() {
1478
1247
  }
1479
1248
  }
1480
1249
  // Send ACK or NACK.
1481
- SendMessageLocked(result.type_url);
1250
+ SendMessageLocked(result.type);
1482
1251
  }
1483
1252
  if (xds_client()->shutting_down_) return true;
1484
1253
  // Keep listening for updates.
@@ -1512,9 +1281,11 @@ void XdsClient::ChannelState::AdsCallState::OnStatusReceivedLocked(
1512
1281
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1513
1282
  char* status_details = grpc_slice_to_c_string(status_details_);
1514
1283
  gpr_log(GPR_INFO,
1515
- "[xds_client %p] ADS call status received. Status = %d, details "
1516
- "= '%s', (chand: %p, ads_calld: %p, call: %p), error '%s'",
1517
- xds_client(), status_code_, status_details, chand(), this, call_,
1284
+ "[xds_client %p] xds server %s: ADS call status received "
1285
+ "(chand=%p, ads_calld=%p, call=%p): "
1286
+ "status=%d, details='%s', error='%s'",
1287
+ xds_client(), chand()->server_.server_uri.c_str(), chand(), this,
1288
+ call_, status_code_, status_details,
1518
1289
  grpc_error_std_string(error).c_str());
1519
1290
  gpr_free(status_details);
1520
1291
  }
@@ -1536,23 +1307,24 @@ bool XdsClient::ChannelState::AdsCallState::IsCurrentCallOnChannel() const {
1536
1307
  return this == chand()->ads_calld_->calld();
1537
1308
  }
1538
1309
 
1539
- std::map<absl::string_view /*authority*/, std::set<absl::string_view /*name*/>>
1310
+ std::vector<std::string>
1540
1311
  XdsClient::ChannelState::AdsCallState::ResourceNamesForRequest(
1541
- const std::string& type_url) {
1542
- std::map<absl::string_view /*authority*/,
1543
- std::set<absl::string_view /*name*/>>
1544
- resource_map;
1545
- auto it = state_map_.find(type_url);
1312
+ const XdsResourceType* type) {
1313
+ std::vector<std::string> resource_names;
1314
+ auto it = state_map_.find(type);
1546
1315
  if (it != state_map_.end()) {
1547
1316
  for (auto& a : it->second.subscribed_resources) {
1317
+ const std::string& authority = a.first;
1548
1318
  for (auto& p : a.second) {
1549
- resource_map[a.first].insert(p.first);
1550
- OrphanablePtr<ResourceState>& state = p.second;
1551
- state->MaybeStartTimer(Ref(DEBUG_LOCATION, "ResourceState"));
1319
+ const XdsResourceKey& resource_key = p.first;
1320
+ resource_names.emplace_back(XdsClient::ConstructFullXdsResourceName(
1321
+ authority, type->type_url(), resource_key));
1322
+ OrphanablePtr<ResourceTimer>& resource_timer = p.second;
1323
+ resource_timer->MaybeStartTimer(Ref(DEBUG_LOCATION, "ResourceTimer"));
1552
1324
  }
1553
1325
  }
1554
1326
  }
1555
- return resource_map;
1327
+ return resource_names;
1556
1328
  }
1557
1329
 
1558
1330
  //
@@ -1642,8 +1414,10 @@ bool XdsClient::ChannelState::LrsCallState::Reporter::SendReportLocked() {
1642
1414
  parent_->call_, &op, 1, &on_report_done_);
1643
1415
  if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) {
1644
1416
  gpr_log(GPR_ERROR,
1645
- "[xds_client %p] calld=%p call_error=%d sending client load report",
1646
- xds_client(), this, call_error);
1417
+ "[xds_client %p] xds server %s: error starting LRS send_message "
1418
+ "batch on calld=%p: call_error=%d",
1419
+ xds_client(), parent_->chand()->server_.server_uri.c_str(), this,
1420
+ call_error);
1647
1421
  GPR_ASSERT(GRPC_CALL_OK == call_error);
1648
1422
  }
1649
1423
  return false;
@@ -1698,13 +1472,14 @@ XdsClient::ChannelState::LrsCallState::LrsCallState(
1698
1472
  // activity in xds_client()->interested_parties_, which is comprised of
1699
1473
  // the polling entities from client_channel.
1700
1474
  GPR_ASSERT(xds_client() != nullptr);
1701
- const auto& method =
1475
+ const char* method =
1702
1476
  chand()->server_.ShouldUseV3()
1703
- ? GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_LOAD_STATS_DOT_V3_DOT_LOADREPORTINGSERVICE_SLASH_STREAMLOADSTATS
1704
- : GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_LOAD_STATS_DOT_V2_DOT_LOADREPORTINGSERVICE_SLASH_STREAMLOADSTATS;
1477
+ ? "/envoy.service.load_stats.v3.LoadReportingService/StreamLoadStats"
1478
+ : "/envoy.service.load_stats.v2.LoadReportingService/StreamLoadStats";
1705
1479
  call_ = grpc_channel_create_pollset_set_call(
1706
1480
  chand()->channel_, nullptr, GRPC_PROPAGATE_DEFAULTS,
1707
- xds_client()->interested_parties_, method, nullptr,
1481
+ xds_client()->interested_parties_,
1482
+ StaticSlice::FromStaticString(method).c_slice(), nullptr,
1708
1483
  GRPC_MILLIS_INF_FUTURE, nullptr);
1709
1484
  GPR_ASSERT(call_ != nullptr);
1710
1485
  // Init the request payload.
@@ -1718,10 +1493,10 @@ XdsClient::ChannelState::LrsCallState::LrsCallState(
1718
1493
  grpc_metadata_array_init(&trailing_metadata_recv_);
1719
1494
  // Start the call.
1720
1495
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1721
- gpr_log(GPR_INFO,
1722
- "[xds_client %p] Starting LRS call (chand: %p, calld: %p, "
1723
- "call: %p)",
1724
- xds_client(), chand(), this, call_);
1496
+ gpr_log(
1497
+ GPR_INFO,
1498
+ "[xds_client %p] xds server %s: starting LRS call (calld=%p, call=%p)",
1499
+ xds_client(), chand()->server_.server_uri.c_str(), this, call_);
1725
1500
  }
1726
1501
  // Create the ops.
1727
1502
  grpc_call_error call_error;
@@ -1881,8 +1656,9 @@ bool XdsClient::ChannelState::LrsCallState::OnResponseReceivedLocked() {
1881
1656
  &new_load_reporting_interval);
1882
1657
  if (parse_error != GRPC_ERROR_NONE) {
1883
1658
  gpr_log(GPR_ERROR,
1884
- "[xds_client %p] LRS response parsing failed. error=%s",
1885
- xds_client(), grpc_error_std_string(parse_error).c_str());
1659
+ "[xds_client %p] xds server %s: LRS response parsing failed: %s",
1660
+ xds_client(), chand()->server_.server_uri.c_str(),
1661
+ grpc_error_std_string(parse_error).c_str());
1886
1662
  GRPC_ERROR_UNREF(parse_error);
1887
1663
  return;
1888
1664
  }
@@ -1890,10 +1666,11 @@ bool XdsClient::ChannelState::LrsCallState::OnResponseReceivedLocked() {
1890
1666
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1891
1667
  gpr_log(
1892
1668
  GPR_INFO,
1893
- "[xds_client %p] LRS response received, %" PRIuPTR
1669
+ "[xds_client %p] xds server %s: LRS response received, %" PRIuPTR
1894
1670
  " cluster names, send_all_clusters=%d, load_report_interval=%" PRId64
1895
1671
  "ms",
1896
- xds_client(), new_cluster_names.size(), send_all_clusters,
1672
+ xds_client(), chand()->server_.server_uri.c_str(),
1673
+ new_cluster_names.size(), send_all_clusters,
1897
1674
  new_load_reporting_interval);
1898
1675
  size_t i = 0;
1899
1676
  for (const auto& name : new_cluster_names) {
@@ -1907,9 +1684,10 @@ bool XdsClient::ChannelState::LrsCallState::OnResponseReceivedLocked() {
1907
1684
  GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS;
1908
1685
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1909
1686
  gpr_log(GPR_INFO,
1910
- "[xds_client %p] Increased load_report_interval to minimum "
1911
- "value %dms",
1912
- xds_client(), GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS);
1687
+ "[xds_client %p] xds server %s: increased load_report_interval "
1688
+ "to minimum value %dms",
1689
+ xds_client(), chand()->server_.server_uri.c_str(),
1690
+ GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS);
1913
1691
  }
1914
1692
  }
1915
1693
  // Ignore identical update.
@@ -1917,10 +1695,11 @@ bool XdsClient::ChannelState::LrsCallState::OnResponseReceivedLocked() {
1917
1695
  cluster_names_ == new_cluster_names &&
1918
1696
  load_reporting_interval_ == new_load_reporting_interval) {
1919
1697
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1920
- gpr_log(GPR_INFO,
1921
- "[xds_client %p] Incoming LRS response identical to current, "
1922
- "ignoring.",
1923
- xds_client());
1698
+ gpr_log(
1699
+ GPR_INFO,
1700
+ "[xds_client %p] xds server %s: incoming LRS response identical "
1701
+ "to current, ignoring.",
1702
+ xds_client(), chand()->server_.server_uri.c_str());
1924
1703
  }
1925
1704
  return;
1926
1705
  }
@@ -1966,9 +1745,11 @@ void XdsClient::ChannelState::LrsCallState::OnStatusReceivedLocked(
1966
1745
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1967
1746
  char* status_details = grpc_slice_to_c_string(status_details_);
1968
1747
  gpr_log(GPR_INFO,
1969
- "[xds_client %p] LRS call status received. Status = %d, details "
1970
- "= '%s', (chand: %p, calld: %p, call: %p), error '%s'",
1971
- xds_client(), status_code_, status_details, chand(), this, call_,
1748
+ "[xds_client %p] xds server %s: LRS call status received "
1749
+ "(chand=%p, calld=%p, call=%p): "
1750
+ "status=%d, details='%s', error='%s'",
1751
+ xds_client(), chand()->server_.server_uri.c_str(), chand(), this,
1752
+ call_, status_code_, status_details,
1972
1753
  grpc_error_std_string(error).c_str());
1973
1754
  gpr_free(status_details);
1974
1755
  }
@@ -2024,7 +1805,7 @@ XdsClient::XdsClient(std::unique_ptr<XdsBootstrap> bootstrap,
2024
1805
  certificate_provider_store_(MakeOrphanable<CertificateProviderStore>(
2025
1806
  bootstrap_->certificate_providers())),
2026
1807
  api_(this, &grpc_xds_client_trace, bootstrap_->node(),
2027
- &bootstrap_->certificate_providers()) {
1808
+ &bootstrap_->certificate_providers(), &symtab_) {
2028
1809
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
2029
1810
  gpr_log(GPR_INFO, "[xds_client %p] creating xds client", this);
2030
1811
  }
@@ -2055,24 +1836,9 @@ void XdsClient::Orphan() {
2055
1836
  {
2056
1837
  MutexLock lock(&mu_);
2057
1838
  shutting_down_ = true;
2058
- // We do not clear cluster_map_ and endpoint_map_ if the xds client was
2059
- // created by the XdsResolver because the maps contain refs for watchers
2060
- // which in turn hold refs to the loadbalancing policies. At this point, it
2061
- // is possible for ADS calls to be in progress. Unreffing the loadbalancing
2062
- // policies before those calls are done would lead to issues such as
2063
- // https://github.com/grpc/grpc/issues/20928.
2064
- for (auto& a : authority_state_map_) {
2065
- a.second.channel_state.reset();
2066
- if (!a.second.listener_map.empty()) {
2067
- a.second.cluster_map.clear();
2068
- a.second.endpoint_map.clear();
2069
- }
2070
- }
2071
- // We clear these invalid resource watchers as cancel never came.
2072
- invalid_listener_watchers_.clear();
2073
- invalid_route_config_watchers_.clear();
2074
- invalid_cluster_watchers_.clear();
2075
- invalid_endpoint_watchers_.clear();
1839
+ // Clear cache and any remaining watchers that may not have been cancelled.
1840
+ authority_state_map_.clear();
1841
+ invalid_watchers_.clear();
2076
1842
  }
2077
1843
  }
2078
1844
 
@@ -2089,19 +1855,17 @@ RefCountedPtr<XdsClient::ChannelState> XdsClient::GetOrCreateChannelStateLocked(
2089
1855
  return channel_state;
2090
1856
  }
2091
1857
 
2092
- void XdsClient::WatchListenerData(
2093
- absl::string_view listener_name,
2094
- RefCountedPtr<ListenerWatcherInterface> watcher) {
2095
- std::string listener_name_str = std::string(listener_name);
2096
- ListenerWatcherInterface* w = watcher.get();
2097
- auto resource = XdsApi::ParseResourceName(listener_name, XdsApi::IsLds);
2098
- if (!resource.ok()) {
1858
+ void XdsClient::WatchResource(const XdsResourceType* type,
1859
+ absl::string_view name,
1860
+ RefCountedPtr<ResourceWatcherInterface> watcher) {
1861
+ ResourceWatcherInterface* w = watcher.get();
1862
+ // Lambda for handling failure cases.
1863
+ auto fail = [&](grpc_error_handle error) mutable {
2099
1864
  {
2100
1865
  MutexLock lock(&mu_);
2101
- invalid_listener_watchers_[w] = watcher;
1866
+ MaybeRegisterResourceTypeLocked(type);
1867
+ invalid_watchers_[w] = watcher;
2102
1868
  }
2103
- grpc_error_handle error = GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrFormat(
2104
- "Unable to parse resource name for listener %s", listener_name));
2105
1869
  work_serializer_.Run(
2106
1870
  // TODO(yashykt): When we move to C++14, capture watcher using
2107
1871
  // std::move()
@@ -2109,107 +1873,52 @@ void XdsClient::WatchListenerData(
2109
1873
  watcher->OnError(error);
2110
1874
  },
2111
1875
  DEBUG_LOCATION);
1876
+ };
1877
+ auto resource_name = ParseXdsResourceName(name, type);
1878
+ if (!resource_name.ok()) {
1879
+ fail(GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrFormat(
1880
+ "Unable to parse resource name for listener %s", name)));
2112
1881
  return;
2113
1882
  }
2114
- {
2115
- MutexLock lock(&mu_);
2116
- AuthorityState& authority_state = authority_state_map_[resource->authority];
2117
- ListenerState& listener_state = authority_state.listener_map[resource->id];
2118
- listener_state.watchers[w] = watcher;
2119
- // If we've already received an LDS update, notify the new watcher
2120
- // immediately.
2121
- if (listener_state.update.has_value()) {
2122
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
2123
- gpr_log(GPR_INFO,
2124
- "[xds_client %p] returning cached listener data for %s", this,
2125
- listener_name_str.c_str());
2126
- }
2127
- auto& value = listener_state.update.value();
2128
- work_serializer_.Schedule(
2129
- // TODO(yashykt): When we move to C++14, capture watcher using
2130
- // std::move()
2131
- [watcher, value]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_) {
2132
- watcher->OnListenerChanged(value);
2133
- },
2134
- DEBUG_LOCATION);
1883
+ // Find server to use.
1884
+ const XdsBootstrap::XdsServer* xds_server = nullptr;
1885
+ absl::string_view authority_name = resource_name->authority;
1886
+ if (absl::ConsumePrefix(&authority_name, "xdstp:")) {
1887
+ auto* authority = bootstrap_->LookupAuthority(std::string(authority_name));
1888
+ if (authority == nullptr) {
1889
+ fail(GRPC_ERROR_CREATE_FROM_CPP_STRING(
1890
+ absl::StrCat("authority \"", authority_name,
1891
+ "\" not present in bootstrap config")));
1892
+ return;
2135
1893
  }
2136
- // If the authority doesn't yet have a channel, set it, creating it if
2137
- // needed.
2138
- if (authority_state.channel_state == nullptr) {
2139
- authority_state.channel_state =
2140
- GetOrCreateChannelStateLocked(bootstrap_->server());
1894
+ if (!authority->xds_servers.empty()) {
1895
+ xds_server = &authority->xds_servers[0];
2141
1896
  }
2142
- authority_state.channel_state->SubscribeLocked(XdsApi::kLdsTypeUrl,
2143
- *resource);
2144
- }
2145
- work_serializer_.DrainQueue();
2146
- }
2147
-
2148
- void XdsClient::CancelListenerDataWatch(absl::string_view listener_name,
2149
- ListenerWatcherInterface* watcher,
2150
- bool delay_unsubscription) {
2151
- MutexLock lock(&mu_);
2152
- if (shutting_down_) return;
2153
- auto resource = XdsApi::ParseResourceName(listener_name, XdsApi::IsLds);
2154
- if (!resource.ok()) return;
2155
- auto& authority_state = authority_state_map_[resource->authority];
2156
- ListenerState& listener_state = authority_state.listener_map[resource->id];
2157
- auto it = listener_state.watchers.find(watcher);
2158
- if (it == listener_state.watchers.end()) {
2159
- invalid_listener_watchers_.erase(watcher);
2160
- return;
2161
- }
2162
- listener_state.watchers.erase(it);
2163
- if (!listener_state.watchers.empty()) return;
2164
- authority_state.listener_map.erase(resource->id);
2165
- xds_server_channel_map_[bootstrap_->server()]->UnsubscribeLocked(
2166
- XdsApi::kLdsTypeUrl, *resource, delay_unsubscription);
2167
- if (!authority_state.HasSubscribedResources()) {
2168
- authority_state.channel_state.reset();
2169
- }
2170
- }
2171
-
2172
- void XdsClient::WatchRouteConfigData(
2173
- absl::string_view route_config_name,
2174
- RefCountedPtr<RouteConfigWatcherInterface> watcher) {
2175
- std::string route_config_name_str = std::string(route_config_name);
2176
- RouteConfigWatcherInterface* w = watcher.get();
2177
- auto resource = XdsApi::ParseResourceName(route_config_name, XdsApi::IsRds);
2178
- if (!resource.ok()) {
2179
- {
2180
- MutexLock lock(&mu_);
2181
- invalid_route_config_watchers_[w] = watcher;
2182
- }
2183
- grpc_error_handle error = GRPC_ERROR_CREATE_FROM_CPP_STRING(
2184
- absl::StrFormat("Unable to parse resource name for route config %s",
2185
- route_config_name));
2186
- work_serializer_.Run(
2187
- // TODO(yashykt): When we move to C++14, capture watcher using
2188
- // std::move()
2189
- [watcher, error]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
2190
- watcher->OnError(error);
2191
- },
2192
- DEBUG_LOCATION);
2193
- return;
2194
1897
  }
1898
+ if (xds_server == nullptr) xds_server = &bootstrap_->server();
2195
1899
  {
2196
1900
  MutexLock lock(&mu_);
2197
- auto& authority_state = authority_state_map_[resource->authority];
2198
- RouteConfigState& route_config_state =
2199
- authority_state.route_config_map[resource->id];
2200
- route_config_state.watchers[w] = watcher;
2201
- // If we've already received an RDS update, notify the new watcher
2202
- // immediately.
2203
- if (route_config_state.update.has_value()) {
1901
+ MaybeRegisterResourceTypeLocked(type);
1902
+ // TODO(donnadionne): If we get a request for an authority that is not
1903
+ // configured in the bootstrap file, reject it.
1904
+ AuthorityState& authority_state =
1905
+ authority_state_map_[resource_name->authority];
1906
+ ResourceState& resource_state =
1907
+ authority_state.resource_map[type][resource_name->key];
1908
+ resource_state.watchers[w] = watcher;
1909
+ // If we already have a cached value for the resource, notify the new
1910
+ // watcher immediately.
1911
+ if (resource_state.resource != nullptr) {
2204
1912
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
2205
1913
  gpr_log(GPR_INFO,
2206
- "[xds_client %p] returning cached route config data for %s",
2207
- this, route_config_name_str.c_str());
1914
+ "[xds_client %p] returning cached listener data for %s", this,
1915
+ std::string(name).c_str());
2208
1916
  }
2209
- auto& value = route_config_state.update.value();
1917
+ auto* value = type->CopyResource(resource_state.resource.get()).release();
2210
1918
  work_serializer_.Schedule(
2211
- [watcher, value]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_) {
2212
- watcher->OnRouteConfigChanged(value);
1919
+ [watcher, value]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1920
+ watcher->OnGenericResourceChanged(value);
1921
+ delete value;
2213
1922
  },
2214
1923
  DEBUG_LOCATION);
2215
1924
  }
@@ -2217,188 +1926,113 @@ void XdsClient::WatchRouteConfigData(
2217
1926
  // needed.
2218
1927
  if (authority_state.channel_state == nullptr) {
2219
1928
  authority_state.channel_state =
2220
- GetOrCreateChannelStateLocked(bootstrap_->server());
1929
+ GetOrCreateChannelStateLocked(*xds_server);
2221
1930
  }
2222
- authority_state.channel_state->SubscribeLocked(XdsApi::kRdsTypeUrl,
2223
- *resource);
1931
+ authority_state.channel_state->SubscribeLocked(type, *resource_name);
2224
1932
  }
2225
1933
  work_serializer_.DrainQueue();
2226
1934
  }
2227
1935
 
2228
- void XdsClient::CancelRouteConfigDataWatch(absl::string_view route_config_name,
2229
- RouteConfigWatcherInterface* watcher,
2230
- bool delay_unsubscription) {
1936
+ void XdsClient::CancelResourceWatch(const XdsResourceType* type,
1937
+ absl::string_view name,
1938
+ ResourceWatcherInterface* watcher,
1939
+ bool delay_unsubscription) {
1940
+ auto resource_name = ParseXdsResourceName(name, type);
2231
1941
  MutexLock lock(&mu_);
2232
- if (shutting_down_) return;
2233
- auto resource = XdsApi::ParseResourceName(route_config_name, XdsApi::IsRds);
2234
- if (!resource.ok()) return;
2235
- auto& authority_state = authority_state_map_[resource->authority];
2236
- RouteConfigState& route_config_state =
2237
- authority_state.route_config_map[resource->id];
2238
- auto it = route_config_state.watchers.find(watcher);
2239
- if (it == route_config_state.watchers.end()) {
2240
- invalid_route_config_watchers_.erase(watcher);
2241
- return;
2242
- }
2243
- route_config_state.watchers.erase(it);
2244
- if (!route_config_state.watchers.empty()) return;
2245
- authority_state.route_config_map.erase(resource->id);
2246
- xds_server_channel_map_[bootstrap_->server()]->UnsubscribeLocked(
2247
- XdsApi::kRdsTypeUrl, *resource, delay_unsubscription);
2248
- if (!authority_state.HasSubscribedResources()) {
2249
- authority_state.channel_state.reset();
2250
- }
2251
- }
2252
-
2253
- void XdsClient::WatchClusterData(
2254
- absl::string_view cluster_name,
2255
- RefCountedPtr<ClusterWatcherInterface> watcher) {
2256
- std::string cluster_name_str = std::string(cluster_name);
2257
- ClusterWatcherInterface* w = watcher.get();
2258
- auto resource = XdsApi::ParseResourceName(cluster_name, XdsApi::IsCds);
2259
- if (!resource.ok()) {
2260
- {
2261
- MutexLock lock(&mu_);
2262
- invalid_cluster_watchers_[w] = watcher;
2263
- }
2264
- grpc_error_handle error = GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrFormat(
2265
- "Unable to parse resource name for cluster %s", cluster_name));
2266
- work_serializer_.Run([watcher, error]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
2267
- work_serializer_) { watcher->OnError(error); },
2268
- DEBUG_LOCATION);
1942
+ if (!resource_name.ok()) {
1943
+ invalid_watchers_.erase(watcher);
2269
1944
  return;
2270
1945
  }
2271
- {
2272
- MutexLock lock(&mu_);
2273
- auto& authority_state = authority_state_map_[resource->authority];
2274
- ClusterState& cluster_state = authority_state.cluster_map[resource->id];
2275
- cluster_state.watchers[w] = watcher;
2276
- // If we've already received a CDS update, notify the new watcher
2277
- // immediately.
2278
- if (cluster_state.update.has_value()) {
2279
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
2280
- gpr_log(GPR_INFO,
2281
- "[xds_client %p] returning cached cluster data for %s", this,
2282
- cluster_name_str.c_str());
2283
- }
2284
- auto& value = cluster_state.update.value();
2285
- work_serializer_.Schedule(
2286
- // TODO(yashykt): When we move to C++14, capture watcher using
2287
- // std::move()
2288
- [watcher, value]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_) {
2289
- watcher->OnClusterChanged(value);
2290
- },
2291
- DEBUG_LOCATION);
2292
- }
2293
- // If the authority doesn't yet have a channel, set it, creating it if
2294
- // needed.
2295
- if (authority_state.channel_state == nullptr) {
2296
- authority_state.channel_state =
2297
- GetOrCreateChannelStateLocked(bootstrap_->server());
2298
- }
2299
- authority_state.channel_state->SubscribeLocked(XdsApi::kCdsTypeUrl,
2300
- *resource);
2301
- }
2302
- work_serializer_.DrainQueue();
2303
- }
2304
-
2305
- void XdsClient::CancelClusterDataWatch(absl::string_view cluster_name,
2306
- ClusterWatcherInterface* watcher,
2307
- bool delay_unsubscription) {
2308
- MutexLock lock(&mu_);
2309
1946
  if (shutting_down_) return;
2310
- auto resource = XdsApi::ParseResourceName(cluster_name, XdsApi::IsCds);
2311
- if (!resource.ok()) return;
2312
- auto& authority_state = authority_state_map_[resource->authority];
2313
- ClusterState& cluster_state = authority_state.cluster_map[resource->id];
2314
- auto it = cluster_state.watchers.find(watcher);
2315
- if (it == cluster_state.watchers.end()) {
2316
- invalid_cluster_watchers_.erase(watcher);
2317
- return;
2318
- }
2319
- cluster_state.watchers.erase(it);
2320
- if (!cluster_state.watchers.empty()) return;
2321
- authority_state.cluster_map.erase(resource->id);
2322
- xds_server_channel_map_[bootstrap_->server()]->UnsubscribeLocked(
2323
- XdsApi::kCdsTypeUrl, *resource, delay_unsubscription);
2324
- if (!authority_state.HasSubscribedResources()) {
2325
- authority_state.channel_state.reset();
2326
- }
2327
- }
2328
-
2329
- void XdsClient::WatchEndpointData(
2330
- absl::string_view eds_service_name,
2331
- RefCountedPtr<EndpointWatcherInterface> watcher) {
2332
- std::string eds_service_name_str = std::string(eds_service_name);
2333
- EndpointWatcherInterface* w = watcher.get();
2334
- auto resource = XdsApi::ParseResourceName(eds_service_name, XdsApi::IsEds);
2335
- if (!resource.ok()) {
2336
- {
2337
- MutexLock lock(&mu_);
2338
- invalid_endpoint_watchers_[w] = watcher;
2339
- }
2340
- grpc_error_handle error = GRPC_ERROR_CREATE_FROM_CPP_STRING(
2341
- absl::StrFormat("Unable to parse resource name for endpoint service %s",
2342
- eds_service_name));
2343
- work_serializer_.Run([watcher, error]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
2344
- work_serializer_) { watcher->OnError(error); },
2345
- DEBUG_LOCATION);
2346
- return;
2347
- }
2348
- {
2349
- MutexLock lock(&mu_);
2350
- auto& authority_state = authority_state_map_[resource->authority];
2351
- EndpointState& endpoint_state = authority_state.endpoint_map[resource->id];
2352
- endpoint_state.watchers[w] = watcher;
2353
- // If we've already received an EDS update, notify the new watcher
2354
- // immediately.
2355
- if (endpoint_state.update.has_value()) {
2356
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
2357
- gpr_log(GPR_INFO,
2358
- "[xds_client %p] returning cached endpoint data for %s", this,
2359
- eds_service_name_str.c_str());
1947
+ // Find authority.
1948
+ auto authority_it = authority_state_map_.find(resource_name->authority);
1949
+ if (authority_it == authority_state_map_.end()) return;
1950
+ AuthorityState& authority_state = authority_it->second;
1951
+ // Find type map.
1952
+ auto type_it = authority_state.resource_map.find(type);
1953
+ if (type_it == authority_state.resource_map.end()) return;
1954
+ auto& type_map = type_it->second;
1955
+ // Find resource key.
1956
+ auto resource_it = type_map.find(resource_name->key);
1957
+ if (resource_it == type_map.end()) return;
1958
+ ResourceState& resource_state = resource_it->second;
1959
+ // Remove watcher.
1960
+ resource_state.watchers.erase(watcher);
1961
+ // Clean up empty map entries, if any.
1962
+ if (resource_state.watchers.empty()) {
1963
+ authority_state.channel_state->UnsubscribeLocked(type, *resource_name,
1964
+ delay_unsubscription);
1965
+ type_map.erase(resource_it);
1966
+ if (type_map.empty()) {
1967
+ authority_state.resource_map.erase(type_it);
1968
+ if (authority_state.resource_map.empty()) {
1969
+ authority_state.channel_state.reset();
2360
1970
  }
2361
- auto& value = endpoint_state.update.value();
2362
- work_serializer_.Schedule(
2363
- [watcher, value]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_) {
2364
- watcher->OnEndpointChanged(value);
2365
- },
2366
- DEBUG_LOCATION);
2367
- }
2368
- // If the authority doesn't yet have a channel, set it, creating it if
2369
- // needed.
2370
- if (authority_state.channel_state == nullptr) {
2371
- authority_state.channel_state =
2372
- GetOrCreateChannelStateLocked(bootstrap_->server());
2373
1971
  }
2374
- authority_state.channel_state->SubscribeLocked(XdsApi::kEdsTypeUrl,
2375
- *resource);
2376
1972
  }
2377
- work_serializer_.DrainQueue();
2378
1973
  }
2379
1974
 
2380
- void XdsClient::CancelEndpointDataWatch(absl::string_view eds_service_name,
2381
- EndpointWatcherInterface* watcher,
2382
- bool delay_unsubscription) {
2383
- MutexLock lock(&mu_);
2384
- if (shutting_down_) return;
2385
- auto resource = XdsApi::ParseResourceName(eds_service_name, XdsApi::IsEds);
2386
- if (!resource.ok()) return;
2387
- auto& authority_state = authority_state_map_[resource->authority];
2388
- EndpointState& endpoint_state = authority_state.endpoint_map[resource->id];
2389
- auto it = endpoint_state.watchers.find(watcher);
2390
- if (it == endpoint_state.watchers.end()) {
2391
- invalid_endpoint_watchers_.erase(watcher);
1975
+ void XdsClient::MaybeRegisterResourceTypeLocked(
1976
+ const XdsResourceType* resource_type) {
1977
+ auto it = resource_types_.find(resource_type->type_url());
1978
+ if (it != resource_types_.end()) {
1979
+ GPR_ASSERT(it->second == resource_type);
2392
1980
  return;
2393
1981
  }
2394
- endpoint_state.watchers.erase(it);
2395
- if (!endpoint_state.watchers.empty()) return;
2396
- authority_state.endpoint_map.erase(resource->id);
2397
- xds_server_channel_map_[bootstrap_->server()]->UnsubscribeLocked(
2398
- XdsApi::kEdsTypeUrl, *resource, delay_unsubscription);
2399
- if (!authority_state.HasSubscribedResources()) {
2400
- authority_state.channel_state.reset();
2401
- }
1982
+ resource_types_.emplace(resource_type->type_url(), resource_type);
1983
+ v2_resource_types_.emplace(resource_type->v2_type_url(), resource_type);
1984
+ resource_type->InitUpbSymtab(symtab_.ptr());
1985
+ }
1986
+
1987
+ const XdsResourceType* XdsClient::GetResourceTypeLocked(
1988
+ absl::string_view resource_type) {
1989
+ auto it = resource_types_.find(resource_type);
1990
+ if (it != resource_types_.end()) return it->second;
1991
+ auto it2 = v2_resource_types_.find(resource_type);
1992
+ if (it2 != v2_resource_types_.end()) return it2->second;
1993
+ return nullptr;
1994
+ }
1995
+
1996
+ absl::StatusOr<XdsClient::XdsResourceName> XdsClient::ParseXdsResourceName(
1997
+ absl::string_view name, const XdsResourceType* type) {
1998
+ // Old-style names use the empty string for authority.
1999
+ // authority is prefixed with "old:" to indicate that it's an old-style name.
2000
+ if (!absl::StartsWith(name, "xdstp:")) {
2001
+ return XdsResourceName{"old:", {std::string(name), {}}};
2002
+ }
2003
+ // New style name. Parse URI.
2004
+ auto uri = URI::Parse(name);
2005
+ if (!uri.ok()) return uri.status();
2006
+ // Split the resource type off of the path to get the id.
2007
+ std::pair<absl::string_view, absl::string_view> path_parts = absl::StrSplit(
2008
+ absl::StripPrefix(uri->path(), "/"), absl::MaxSplits('/', 1));
2009
+ if (!type->IsType(path_parts.first, nullptr)) {
2010
+ return absl::InvalidArgumentError(
2011
+ "xdstp URI path must indicate valid xDS resource type");
2012
+ }
2013
+ // Canonicalize order of query params.
2014
+ std::vector<URI::QueryParam> query_params;
2015
+ for (const auto& p : uri->query_parameter_map()) {
2016
+ query_params.emplace_back(
2017
+ URI::QueryParam{std::string(p.first), std::string(p.second)});
2018
+ }
2019
+ return XdsResourceName{
2020
+ absl::StrCat("xdstp:", uri->authority()),
2021
+ {std::string(path_parts.second), std::move(query_params)}};
2022
+ }
2023
+
2024
+ std::string XdsClient::ConstructFullXdsResourceName(
2025
+ absl::string_view authority, absl::string_view resource_type,
2026
+ const XdsResourceKey& key) {
2027
+ if (absl::ConsumePrefix(&authority, "xdstp:")) {
2028
+ auto uri = URI::Create("xdstp", std::string(authority),
2029
+ absl::StrCat("/", resource_type, "/", key.id),
2030
+ key.query_params, /*fragment=*/"");
2031
+ GPR_ASSERT(uri.ok());
2032
+ return uri->ToString();
2033
+ }
2034
+ // Old-style name.
2035
+ return key.id;
2402
2036
  }
2403
2037
 
2404
2038
  RefCountedPtr<XdsClusterDropStats> XdsClient::AddClusterDropStats(
@@ -2431,9 +2065,10 @@ RefCountedPtr<XdsClusterDropStats> XdsClient::AddClusterDropStats(
2431
2065
  it->first.second /*eds_service_name*/);
2432
2066
  load_report_state.drop_stats = cluster_drop_stats.get();
2433
2067
  }
2434
- auto resource = XdsApi::ParseResourceName(cluster_name, XdsApi::IsCds);
2435
- GPR_ASSERT(resource.ok());
2436
- auto a = authority_state_map_.find(resource->authority);
2068
+ auto resource_name =
2069
+ ParseXdsResourceName(cluster_name, XdsClusterResourceType::Get());
2070
+ GPR_ASSERT(resource_name.ok());
2071
+ auto a = authority_state_map_.find(resource_name->authority);
2437
2072
  if (a != authority_state_map_.end()) {
2438
2073
  a->second.channel_state->MaybeStartLrsCall();
2439
2074
  }
@@ -2493,9 +2128,10 @@ RefCountedPtr<XdsClusterLocalityStats> XdsClient::AddClusterLocalityStats(
2493
2128
  std::move(locality));
2494
2129
  locality_state.locality_stats = cluster_locality_stats.get();
2495
2130
  }
2496
- auto resource = XdsApi::ParseResourceName(cluster_name, XdsApi::IsCds);
2497
- GPR_ASSERT(resource.ok());
2498
- auto a = authority_state_map_.find(resource->authority);
2131
+ auto resource_name =
2132
+ ParseXdsResourceName(cluster_name, XdsClusterResourceType::Get());
2133
+ GPR_ASSERT(resource_name.ok());
2134
+ auto a = authority_state_map_.find(resource_name->authority);
2499
2135
  if (a != authority_state_map_.end()) {
2500
2136
  a->second.channel_state->MaybeStartLrsCall();
2501
2137
  }
@@ -2534,56 +2170,25 @@ void XdsClient::ResetBackoff() {
2534
2170
  }
2535
2171
 
2536
2172
  void XdsClient::NotifyOnErrorLocked(grpc_error_handle error) {
2537
- std::set<RefCountedPtr<ListenerWatcherInterface>> listener_watchers;
2538
- std::set<RefCountedPtr<RouteConfigWatcherInterface>> route_config_watchers;
2539
- std::set<RefCountedPtr<ClusterWatcherInterface>> cluster_watchers;
2540
- std::set<RefCountedPtr<EndpointWatcherInterface>> endpoint_watchers;
2541
- for (const auto& a : authority_state_map_) {
2542
- for (const auto& p : a.second.listener_map) {
2543
- const ListenerState& listener_state = p.second;
2544
- for (const auto& q : listener_state.watchers) {
2545
- listener_watchers.insert(q.second);
2546
- }
2547
- }
2548
- for (const auto& p : a.second.route_config_map) {
2549
- const RouteConfigState& route_config_state = p.second;
2550
- for (const auto& q : route_config_state.watchers) {
2551
- route_config_watchers.insert(q.second);
2552
- }
2553
- }
2554
- for (const auto& p : a.second.cluster_map) {
2555
- const ClusterState& cluster_state = p.second;
2556
- for (const auto& q : cluster_state.watchers) {
2557
- cluster_watchers.insert(q.second);
2558
- }
2559
- }
2560
- for (const auto& p : a.second.endpoint_map) {
2561
- const EndpointState& endpoint_state = p.second;
2562
- for (const auto& q : endpoint_state.watchers) {
2563
- endpoint_watchers.insert(q.second);
2173
+ std::set<RefCountedPtr<ResourceWatcherInterface>> watchers;
2174
+ for (const auto& a : authority_state_map_) { // authority
2175
+ for (const auto& t : a.second.resource_map) { // type
2176
+ for (const auto& r : t.second) { // resource id
2177
+ for (const auto& w : r.second.watchers) { // watchers
2178
+ watchers.insert(w.second);
2179
+ }
2564
2180
  }
2565
2181
  }
2566
2182
  }
2567
2183
  work_serializer_.Schedule(
2568
- // TODO(yashykt): When we move to C++14, capture *_watchers using
2184
+ // TODO(yashykt): When we move to C++14, capture watchers using
2569
2185
  // std::move()
2570
- [listener_watchers, route_config_watchers, cluster_watchers,
2571
- endpoint_watchers, error]()
2572
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_) {
2573
- for (const auto& watcher : listener_watchers) {
2574
- watcher->OnError(GRPC_ERROR_REF(error));
2575
- }
2576
- for (const auto& watcher : route_config_watchers) {
2577
- watcher->OnError(GRPC_ERROR_REF(error));
2578
- }
2579
- for (const auto& watcher : cluster_watchers) {
2580
- watcher->OnError(GRPC_ERROR_REF(error));
2581
- }
2582
- for (const auto& watcher : endpoint_watchers) {
2583
- watcher->OnError(GRPC_ERROR_REF(error));
2584
- }
2585
- GRPC_ERROR_UNREF(error);
2586
- },
2186
+ [watchers, error]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_) {
2187
+ for (const auto& watcher : watchers) {
2188
+ watcher->OnError(GRPC_ERROR_REF(error));
2189
+ }
2190
+ GRPC_ERROR_UNREF(error);
2191
+ },
2587
2192
  DEBUG_LOCATION);
2588
2193
  }
2589
2194
 
@@ -2671,35 +2276,18 @@ XdsApi::ClusterLoadReportMap XdsClient::BuildLoadReportSnapshotLocked(
2671
2276
  std::string XdsClient::DumpClientConfigBinary() {
2672
2277
  MutexLock lock(&mu_);
2673
2278
  XdsApi::ResourceTypeMetadataMap resource_type_metadata_map;
2674
- auto& lds_map = resource_type_metadata_map[XdsApi::kLdsTypeUrl];
2675
- auto& rds_map = resource_type_metadata_map[XdsApi::kRdsTypeUrl];
2676
- auto& cds_map = resource_type_metadata_map[XdsApi::kCdsTypeUrl];
2677
- auto& eds_map = resource_type_metadata_map[XdsApi::kEdsTypeUrl];
2678
- for (auto& a : authority_state_map_) {
2279
+ for (const auto& a : authority_state_map_) { // authority
2679
2280
  const std::string& authority = a.first;
2680
- // Collect resource metadata from listeners
2681
- for (auto& p : a.second.listener_map) {
2682
- const std::string& listener_name = p.first;
2683
- lds_map[XdsApi::ConstructFullResourceName(
2684
- authority, XdsApi::kLdsTypeUrl, listener_name)] = &p.second.meta;
2685
- }
2686
- // Collect resource metadata from route configs
2687
- for (auto& p : a.second.route_config_map) {
2688
- const std::string& route_config_name = p.first;
2689
- rds_map[XdsApi::ConstructFullResourceName(
2690
- authority, XdsApi::kRdsTypeUrl, route_config_name)] = &p.second.meta;
2691
- }
2692
- // Collect resource metadata from clusters
2693
- for (auto& p : a.second.cluster_map) {
2694
- const std::string& cluster_name = p.first;
2695
- cds_map[XdsApi::ConstructFullResourceName(authority, XdsApi::kCdsTypeUrl,
2696
- cluster_name)] = &p.second.meta;
2697
- }
2698
- // Collect resource metadata from endpoints
2699
- for (auto& p : a.second.endpoint_map) {
2700
- const std::string& endpoint_name = p.first;
2701
- eds_map[XdsApi::ConstructFullResourceName(
2702
- authority, XdsApi::kEdsTypeUrl, endpoint_name)] = &p.second.meta;
2281
+ for (const auto& t : a.second.resource_map) { // type
2282
+ const XdsResourceType* type = t.first;
2283
+ auto& resource_metadata_map =
2284
+ resource_type_metadata_map[type->type_url()];
2285
+ for (const auto& r : t.second) { // resource id
2286
+ const XdsResourceKey& resource_key = r.first;
2287
+ const ResourceState& resource_state = r.second;
2288
+ resource_metadata_map[ConstructFullXdsResourceName(
2289
+ authority, type->type_url(), resource_key)] = &resource_state.meta;
2290
+ }
2703
2291
  }
2704
2292
  }
2705
2293
  // Assemble config dump messages
@@ -2713,6 +2301,7 @@ std::string XdsClient::DumpClientConfigBinary() {
2713
2301
  void XdsClientGlobalInit() {
2714
2302
  g_mu = new Mutex;
2715
2303
  XdsHttpFilterRegistry::Init();
2304
+ XdsChannelCredsRegistry::Init();
2716
2305
  }
2717
2306
 
2718
2307
  // TODO(roth): Find a better way to clear the fallback config that does
@@ -2722,6 +2311,7 @@ void XdsClientGlobalShutdown() ABSL_NO_THREAD_SAFETY_ANALYSIS {
2722
2311
  g_fallback_bootstrap_config = nullptr;
2723
2312
  delete g_mu;
2724
2313
  g_mu = nullptr;
2314
+ XdsChannelCredsRegistry::Shutdown();
2725
2315
  XdsHttpFilterRegistry::Shutdown();
2726
2316
  }
2727
2317