grpc 1.60.2 → 1.61.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +208 -165
  3. data/include/grpc/event_engine/event_engine.h +59 -12
  4. data/include/grpc/event_engine/internal/memory_allocator_impl.h +6 -0
  5. data/include/grpc/event_engine/internal/slice_cast.h +12 -0
  6. data/include/grpc/event_engine/memory_allocator.h +3 -1
  7. data/include/grpc/event_engine/slice.h +5 -0
  8. data/include/grpc/grpc_security.h +22 -1
  9. data/include/grpc/impl/call.h +29 -0
  10. data/include/grpc/impl/channel_arg_names.h +12 -1
  11. data/include/grpc/impl/slice_type.h +1 -1
  12. data/include/grpc/module.modulemap +1 -0
  13. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +54 -7
  14. data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +20 -6
  15. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +10 -13
  16. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +18 -10
  17. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +326 -0
  18. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h +143 -0
  19. data/src/core/ext/filters/client_channel/backend_metric.cc +2 -2
  20. data/src/core/ext/filters/client_channel/client_channel.cc +32 -6
  21. data/src/core/ext/filters/client_channel/client_channel_internal.h +2 -0
  22. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +54 -21
  24. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +3 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +2 -1
  26. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +12 -15
  27. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +8 -5
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +139 -92
  29. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +9 -4
  30. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +9 -4
  31. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +10 -11
  32. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +94 -93
  33. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +5 -3
  34. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +12 -15
  35. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +38 -16
  36. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +25 -28
  37. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +10 -10
  38. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +37 -35
  39. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -9
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +504 -461
  41. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +232 -122
  42. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +8 -6
  43. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +642 -251
  44. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h +2 -6
  45. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +7 -8
  46. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -1
  47. data/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +3 -1
  48. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -2
  49. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -2
  50. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +6 -8
  51. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.cc +1031 -0
  52. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h +277 -0
  53. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +128 -270
  54. data/src/core/ext/filters/client_channel/resolver/xds/{xds_resolver.h → xds_resolver_attributes.h} +5 -4
  55. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.cc +25 -0
  56. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.h +30 -0
  57. data/src/core/ext/filters/client_channel/retry_filter.cc +1 -0
  58. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +35 -17
  59. data/src/core/ext/filters/deadline/deadline_filter.cc +12 -0
  60. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +17 -13
  61. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +13 -4
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +23 -32
  63. data/src/core/ext/filters/http/client/http_client_filter.h +10 -5
  64. data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
  65. data/src/core/ext/filters/http/client_authority_filter.h +12 -4
  66. data/src/core/ext/filters/http/http_filters_plugin.cc +42 -20
  67. data/src/core/ext/filters/http/message_compress/compression_filter.cc +55 -80
  68. data/src/core/ext/filters/http/message_compress/compression_filter.h +54 -12
  69. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.cc +325 -0
  70. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.h +139 -0
  71. data/src/core/ext/filters/http/server/http_server_filter.cc +41 -41
  72. data/src/core/ext/filters/http/server/http_server_filter.h +11 -4
  73. data/src/core/ext/filters/message_size/message_size_filter.cc +56 -76
  74. data/src/core/ext/filters/message_size/message_size_filter.h +35 -23
  75. data/src/core/ext/filters/rbac/rbac_filter.cc +15 -11
  76. data/src/core/ext/filters/rbac/rbac_filter.h +11 -4
  77. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +25 -13
  78. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +47 -50
  79. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +21 -4
  80. data/src/core/ext/transport/chttp2/alpn/alpn.cc +1 -1
  81. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -2
  82. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +11 -2
  83. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +68 -145
  84. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -3
  85. data/src/core/ext/transport/chttp2/transport/flow_control.cc +21 -82
  86. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -8
  87. data/src/core/ext/transport/chttp2/transport/frame.cc +506 -0
  88. data/src/core/ext/transport/chttp2/transport/frame.h +214 -0
  89. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
  90. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +33 -79
  91. data/src/core/ext/transport/chttp2/transport/frame_settings.h +4 -7
  92. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -36
  93. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -2
  94. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +122 -32
  95. data/src/core/ext/transport/chttp2/transport/http2_settings.h +142 -37
  96. data/src/core/ext/transport/chttp2/transport/internal.h +1 -22
  97. data/src/core/ext/transport/chttp2/transport/parsing.cc +23 -37
  98. data/src/core/ext/transport/chttp2/transport/writing.cc +26 -58
  99. data/src/core/ext/transport/inproc/inproc_transport.cc +172 -13
  100. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +712 -0
  101. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +151 -0
  102. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +33 -0
  103. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +133 -0
  104. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +50 -0
  105. data/src/core/ext/xds/certificate_provider_store.cc +2 -1
  106. data/src/core/ext/xds/certificate_provider_store.h +0 -5
  107. data/src/core/ext/xds/xds_api.cc +31 -18
  108. data/src/core/ext/xds/xds_api.h +2 -2
  109. data/src/core/ext/xds/xds_bootstrap.h +3 -0
  110. data/src/core/ext/xds/xds_certificate_provider.cc +88 -287
  111. data/src/core/ext/xds/xds_certificate_provider.h +44 -111
  112. data/src/core/ext/xds/xds_client.cc +420 -414
  113. data/src/core/ext/xds/xds_client.h +31 -22
  114. data/src/core/ext/xds/xds_client_grpc.cc +3 -1
  115. data/src/core/ext/xds/xds_cluster.cc +104 -11
  116. data/src/core/ext/xds/xds_cluster.h +9 -1
  117. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +9 -5
  118. data/src/core/ext/xds/xds_common_types.cc +14 -10
  119. data/src/core/ext/xds/xds_endpoint.cc +9 -4
  120. data/src/core/ext/xds/xds_endpoint.h +5 -1
  121. data/src/core/ext/xds/xds_health_status.cc +12 -2
  122. data/src/core/ext/xds/xds_health_status.h +4 -2
  123. data/src/core/ext/xds/xds_http_rbac_filter.cc +5 -3
  124. data/src/core/ext/xds/xds_listener.cc +14 -8
  125. data/src/core/ext/xds/xds_resource_type_impl.h +6 -4
  126. data/src/core/ext/xds/xds_route_config.cc +34 -22
  127. data/src/core/ext/xds/xds_route_config.h +1 -0
  128. data/src/core/ext/xds/xds_server_config_fetcher.cc +61 -57
  129. data/src/core/ext/xds/xds_transport.h +3 -0
  130. data/src/core/ext/xds/xds_transport_grpc.cc +47 -50
  131. data/src/core/ext/xds/xds_transport_grpc.h +4 -0
  132. data/src/core/lib/channel/call_tracer.cc +12 -0
  133. data/src/core/lib/channel/call_tracer.h +17 -3
  134. data/src/core/lib/channel/channel_args.cc +24 -14
  135. data/src/core/lib/channel/channel_args.h +74 -13
  136. data/src/core/lib/channel/channel_stack.cc +27 -0
  137. data/src/core/lib/channel/channel_stack.h +10 -10
  138. data/src/core/lib/channel/connected_channel.cc +64 -18
  139. data/src/core/lib/channel/promise_based_filter.h +1041 -1
  140. data/src/core/lib/channel/server_call_tracer_filter.cc +43 -35
  141. data/src/core/lib/compression/compression_internal.cc +0 -3
  142. data/src/core/lib/event_engine/ares_resolver.cc +35 -14
  143. data/src/core/lib/event_engine/ares_resolver.h +9 -10
  144. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +8 -1
  145. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +132 -0
  146. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +61 -0
  147. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +52 -36
  148. data/src/core/lib/event_engine/posix_engine/posix_engine.h +4 -9
  149. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +11 -3
  150. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +9 -2
  151. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +7 -0
  152. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +17 -27
  153. data/src/core/lib/event_engine/posix_engine/timer_manager.h +0 -3
  154. data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +55 -0
  155. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +114 -0
  156. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.h +51 -0
  157. data/src/core/lib/event_engine/windows/windows_engine.cc +7 -7
  158. data/src/core/lib/experiments/config.cc +13 -0
  159. data/src/core/lib/experiments/config.h +3 -0
  160. data/src/core/lib/experiments/experiments.cc +245 -366
  161. data/src/core/lib/experiments/experiments.h +50 -156
  162. data/src/core/lib/gprpp/debug_location.h +13 -0
  163. data/src/core/lib/gprpp/dual_ref_counted.h +36 -7
  164. data/src/core/lib/gprpp/orphanable.h +27 -0
  165. data/src/core/lib/gprpp/ref_counted.h +63 -22
  166. data/src/core/lib/gprpp/ref_counted_ptr.h +70 -27
  167. data/src/core/lib/gprpp/ref_counted_string.h +13 -0
  168. data/src/core/lib/gprpp/status_helper.cc +1 -2
  169. data/src/core/lib/iomgr/combiner.cc +15 -51
  170. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +31 -0
  171. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +16 -0
  172. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -3
  173. data/src/core/lib/load_balancing/lb_policy.h +1 -1
  174. data/src/core/lib/promise/activity.cc +17 -2
  175. data/src/core/lib/promise/activity.h +5 -4
  176. data/src/core/lib/promise/all_ok.h +80 -0
  177. data/src/core/lib/promise/detail/join_state.h +2077 -0
  178. data/src/core/lib/promise/detail/promise_factory.h +1 -0
  179. data/src/core/lib/promise/detail/promise_like.h +8 -1
  180. data/src/core/lib/promise/detail/seq_state.h +3458 -150
  181. data/src/core/lib/promise/detail/status.h +42 -5
  182. data/src/core/lib/promise/for_each.h +13 -1
  183. data/src/core/lib/promise/if.h +4 -0
  184. data/src/core/lib/promise/latch.h +6 -3
  185. data/src/core/lib/promise/party.cc +33 -31
  186. data/src/core/lib/promise/party.h +142 -6
  187. data/src/core/lib/promise/poll.h +39 -13
  188. data/src/core/lib/promise/promise.h +4 -0
  189. data/src/core/lib/promise/seq.h +107 -7
  190. data/src/core/lib/promise/status_flag.h +196 -0
  191. data/src/core/lib/promise/try_join.h +132 -0
  192. data/src/core/lib/promise/try_seq.h +132 -10
  193. data/src/core/lib/resolver/endpoint_addresses.cc +0 -1
  194. data/src/core/lib/resolver/endpoint_addresses.h +48 -0
  195. data/src/core/lib/resource_quota/arena.h +2 -2
  196. data/src/core/lib/resource_quota/memory_quota.cc +57 -8
  197. data/src/core/lib/resource_quota/memory_quota.h +6 -0
  198. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +14 -11
  199. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +14 -5
  200. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +4 -0
  201. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +4 -0
  202. data/src/core/lib/security/credentials/external/external_account_credentials.cc +28 -20
  203. data/src/core/lib/security/credentials/external/external_account_credentials.h +4 -0
  204. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +4 -0
  205. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -0
  206. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +4 -0
  207. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +4 -0
  208. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +2 -1
  209. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +0 -3
  210. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +12 -0
  211. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc +22 -5
  212. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h +1 -5
  213. data/src/core/lib/security/credentials/tls/tls_credentials.cc +16 -0
  214. data/src/core/lib/security/credentials/xds/xds_credentials.cc +21 -28
  215. data/src/core/lib/security/credentials/xds/xds_credentials.h +2 -4
  216. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +4 -3
  217. data/src/core/lib/security/transport/auth_filters.h +71 -4
  218. data/src/core/lib/security/transport/client_auth_filter.cc +2 -4
  219. data/src/core/lib/security/transport/legacy_server_auth_filter.cc +244 -0
  220. data/src/core/lib/security/transport/server_auth_filter.cc +70 -90
  221. data/src/core/lib/slice/slice_buffer.h +3 -0
  222. data/src/core/lib/surface/builtins.cc +1 -1
  223. data/src/core/lib/surface/call.cc +683 -196
  224. data/src/core/lib/surface/call.h +26 -13
  225. data/src/core/lib/surface/call_trace.cc +42 -1
  226. data/src/core/lib/surface/channel.cc +0 -1
  227. data/src/core/lib/surface/channel.h +0 -6
  228. data/src/core/lib/surface/channel_init.h +26 -0
  229. data/src/core/lib/surface/init.cc +14 -8
  230. data/src/core/lib/surface/server.cc +256 -237
  231. data/src/core/lib/surface/server.h +26 -54
  232. data/src/core/lib/surface/version.cc +2 -2
  233. data/src/core/lib/surface/wait_for_cq_end_op.h +94 -0
  234. data/src/core/lib/transport/call_final_info.cc +38 -0
  235. data/src/core/lib/transport/call_final_info.h +54 -0
  236. data/src/core/lib/transport/connectivity_state.cc +3 -2
  237. data/src/core/lib/transport/connectivity_state.h +4 -0
  238. data/src/core/lib/transport/metadata_batch.h +4 -4
  239. data/src/core/lib/transport/transport.cc +70 -19
  240. data/src/core/lib/transport/transport.h +395 -25
  241. data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -0
  242. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +0 -3
  243. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  244. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
  245. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
  246. data/src/core/tsi/ssl_transport_security.cc +65 -43
  247. data/src/ruby/ext/grpc/rb_channel_args.c +3 -1
  248. data/src/ruby/ext/grpc/rb_grpc.c +0 -1
  249. data/src/ruby/ext/grpc/rb_grpc.h +0 -2
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  252. data/src/ruby/lib/grpc/version.rb +1 -1
  253. data/third_party/upb/upb/reflection/def_pool.h +2 -2
  254. data/third_party/zlib/adler32.c +5 -27
  255. data/third_party/zlib/compress.c +5 -16
  256. data/third_party/zlib/crc32.c +86 -162
  257. data/third_party/zlib/deflate.c +233 -336
  258. data/third_party/zlib/deflate.h +8 -8
  259. data/third_party/zlib/gzguts.h +11 -12
  260. data/third_party/zlib/infback.c +7 -23
  261. data/third_party/zlib/inffast.c +1 -4
  262. data/third_party/zlib/inffast.h +1 -1
  263. data/third_party/zlib/inflate.c +30 -99
  264. data/third_party/zlib/inftrees.c +6 -11
  265. data/third_party/zlib/inftrees.h +3 -3
  266. data/third_party/zlib/trees.c +224 -302
  267. data/third_party/zlib/uncompr.c +4 -12
  268. data/third_party/zlib/zconf.h +6 -2
  269. data/third_party/zlib/zlib.h +191 -188
  270. data/third_party/zlib/zutil.c +16 -44
  271. data/third_party/zlib/zutil.h +10 -10
  272. metadata +35 -13
  273. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +0 -1173
  274. data/src/core/lib/event_engine/memory_allocator.cc +0 -74
  275. data/src/core/lib/transport/pid_controller.cc +0 -51
  276. data/src/core/lib/transport/pid_controller.h +0 -116
  277. data/third_party/upb/upb/collections/array.h +0 -17
  278. data/third_party/upb/upb/collections/map.h +0 -17
  279. data/third_party/upb/upb/upb.hpp +0 -18
@@ -0,0 +1,1031 @@
1
+ //
2
+ // Copyright 2019 gRPC authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+
17
+ #include <grpc/support/port_platform.h>
18
+
19
+ #include "src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h"
20
+
21
+ #include "absl/strings/str_join.h"
22
+
23
+ #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h"
24
+ #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
25
+ #include "src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.h"
26
+ #include "src/core/ext/xds/xds_routing.h"
27
+ #include "src/core/lib/config/core_configuration.h"
28
+ #include "src/core/lib/gprpp/match.h"
29
+
30
+ namespace grpc_core {
31
+
32
+ namespace {
33
+
34
+ // Max depth of aggregate cluster dependency graph.
35
+ constexpr int kMaxXdsAggregateClusterRecursionDepth = 16;
36
+
37
+ } // namespace
38
+
39
+ //
40
+ // XdsDependencyManager::XdsConfig::ClusterConfig
41
+ //
42
+
43
+ XdsDependencyManager::XdsConfig::ClusterConfig::ClusterConfig(
44
+ std::shared_ptr<const XdsClusterResource> cluster,
45
+ std::shared_ptr<const XdsEndpointResource> endpoints,
46
+ std::string resolution_note)
47
+ : cluster(std::move(cluster)),
48
+ children(absl::in_place_type_t<EndpointConfig>(), std::move(endpoints),
49
+ std::move(resolution_note)) {}
50
+
51
+ XdsDependencyManager::XdsConfig::ClusterConfig::ClusterConfig(
52
+ std::shared_ptr<const XdsClusterResource> cluster,
53
+ std::vector<absl::string_view> leaf_clusters)
54
+ : cluster(std::move(cluster)),
55
+ children(absl::in_place_type_t<AggregateConfig>(),
56
+ std::move(leaf_clusters)) {}
57
+
58
+ //
59
+ // XdsDependencyManager::XdsConfig
60
+ //
61
+
62
+ std::string XdsDependencyManager::XdsConfig::ToString() const {
63
+ std::vector<std::string> parts = {
64
+ "{\n listener: {", listener->ToString(),
65
+ "}\n route_config: {", route_config->ToString(),
66
+ "}\n virtual_host: {", virtual_host->ToString(),
67
+ "}\n clusters: {\n"};
68
+ for (const auto& p : clusters) {
69
+ parts.push_back(absl::StrCat(" \"", p.first, "\": "));
70
+ if (!p.second.ok()) {
71
+ parts.push_back(p.second.status().ToString());
72
+ parts.push_back("\n");
73
+ } else {
74
+ parts.push_back(
75
+ absl::StrCat(" {\n"
76
+ " cluster: {",
77
+ p.second->cluster->ToString(), "}\n"));
78
+ Match(
79
+ p.second->children,
80
+ [&](const ClusterConfig::EndpointConfig& endpoint_config) {
81
+ parts.push_back(
82
+ absl::StrCat(" endpoints: {",
83
+ endpoint_config.endpoints == nullptr
84
+ ? "<null>"
85
+ : endpoint_config.endpoints->ToString(),
86
+ "}\n"
87
+ " resolution_note: \"",
88
+ endpoint_config.resolution_note, "\"\n"));
89
+ },
90
+ [&](const ClusterConfig::AggregateConfig& aggregate_config) {
91
+ parts.push_back(absl::StrCat(
92
+ " leaf_clusters: [",
93
+ absl::StrJoin(aggregate_config.leaf_clusters, ", "), "]\n"));
94
+ });
95
+ parts.push_back(
96
+ " }\n"
97
+ " ]\n");
98
+ }
99
+ }
100
+ parts.push_back(" }\n}");
101
+ return absl::StrJoin(parts, "");
102
+ }
103
+
104
+ //
105
+ // XdsDependencyManager::ListenerWatcher
106
+ //
107
+
108
+ class XdsDependencyManager::ListenerWatcher
109
+ : public XdsListenerResourceType::WatcherInterface {
110
+ public:
111
+ explicit ListenerWatcher(RefCountedPtr<XdsDependencyManager> dependency_mgr)
112
+ : dependency_mgr_(std::move(dependency_mgr)) {}
113
+
114
+ void OnResourceChanged(
115
+ std::shared_ptr<const XdsListenerResource> listener,
116
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
117
+ dependency_mgr_->work_serializer_->Run(
118
+ [dependency_mgr = dependency_mgr_, listener = std::move(listener),
119
+ read_delay_handle = std::move(read_delay_handle)]() mutable {
120
+ dependency_mgr->OnListenerUpdate(std::move(listener));
121
+ },
122
+ DEBUG_LOCATION);
123
+ }
124
+
125
+ void OnError(
126
+ absl::Status status,
127
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
128
+ dependency_mgr_->work_serializer_->Run(
129
+ [dependency_mgr = dependency_mgr_, status = std::move(status),
130
+ read_delay_handle = std::move(read_delay_handle)]() mutable {
131
+ dependency_mgr->OnError(dependency_mgr->listener_resource_name_,
132
+ std::move(status));
133
+ },
134
+ DEBUG_LOCATION);
135
+ }
136
+
137
+ void OnResourceDoesNotExist(
138
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
139
+ dependency_mgr_->work_serializer_->Run(
140
+ [dependency_mgr = dependency_mgr_,
141
+ read_delay_handle = std::move(read_delay_handle)]() {
142
+ dependency_mgr->OnResourceDoesNotExist(
143
+ absl::StrCat(dependency_mgr->listener_resource_name_,
144
+ ": xDS listener resource does not exist"));
145
+ },
146
+ DEBUG_LOCATION);
147
+ }
148
+
149
+ private:
150
+ RefCountedPtr<XdsDependencyManager> dependency_mgr_;
151
+ };
152
+
153
+ //
154
+ // XdsDependencyManager::RouteConfigWatcher
155
+ //
156
+
157
+ class XdsDependencyManager::RouteConfigWatcher
158
+ : public XdsRouteConfigResourceType::WatcherInterface {
159
+ public:
160
+ RouteConfigWatcher(RefCountedPtr<XdsDependencyManager> dependency_mgr,
161
+ std::string name)
162
+ : dependency_mgr_(std::move(dependency_mgr)), name_(std::move(name)) {}
163
+
164
+ void OnResourceChanged(
165
+ std::shared_ptr<const XdsRouteConfigResource> route_config,
166
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
167
+ dependency_mgr_->work_serializer_->Run(
168
+ [self = RefAsSubclass<RouteConfigWatcher>(),
169
+ route_config = std::move(route_config),
170
+ read_delay_handle = std::move(read_delay_handle)]() mutable {
171
+ self->dependency_mgr_->OnRouteConfigUpdate(self->name_,
172
+ std::move(route_config));
173
+ },
174
+ DEBUG_LOCATION);
175
+ }
176
+
177
+ void OnError(
178
+ absl::Status status,
179
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
180
+ dependency_mgr_->work_serializer_->Run(
181
+ [self = RefAsSubclass<RouteConfigWatcher>(), status = std::move(status),
182
+ read_delay_handle = std::move(read_delay_handle)]() mutable {
183
+ self->dependency_mgr_->OnError(self->name_, std::move(status));
184
+ },
185
+ DEBUG_LOCATION);
186
+ }
187
+
188
+ void OnResourceDoesNotExist(
189
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
190
+ dependency_mgr_->work_serializer_->Run(
191
+ [self = RefAsSubclass<RouteConfigWatcher>(),
192
+ read_delay_handle = std::move(read_delay_handle)]() {
193
+ self->dependency_mgr_->OnResourceDoesNotExist(absl::StrCat(
194
+ self->name_,
195
+ ": xDS route configuration resource does not exist"));
196
+ },
197
+ DEBUG_LOCATION);
198
+ }
199
+
200
+ private:
201
+ RefCountedPtr<XdsDependencyManager> dependency_mgr_;
202
+ std::string name_;
203
+ };
204
+
205
+ //
206
+ // XdsDependencyManager::ClusterWatcher
207
+ //
208
+
209
+ class XdsDependencyManager::ClusterWatcher
210
+ : public XdsClusterResourceType::WatcherInterface {
211
+ public:
212
+ ClusterWatcher(RefCountedPtr<XdsDependencyManager> dependency_mgr,
213
+ absl::string_view name)
214
+ : dependency_mgr_(std::move(dependency_mgr)), name_(name) {}
215
+
216
+ void OnResourceChanged(
217
+ std::shared_ptr<const XdsClusterResource> cluster,
218
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
219
+ dependency_mgr_->work_serializer_->Run(
220
+ [self = RefAsSubclass<ClusterWatcher>(), cluster = std::move(cluster),
221
+ read_delay_handle = std::move(read_delay_handle)]() mutable {
222
+ self->dependency_mgr_->OnClusterUpdate(self->name_,
223
+ std::move(cluster));
224
+ },
225
+ DEBUG_LOCATION);
226
+ }
227
+
228
+ void OnError(
229
+ absl::Status status,
230
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
231
+ dependency_mgr_->work_serializer_->Run(
232
+ [self = RefAsSubclass<ClusterWatcher>(), status = std::move(status),
233
+ read_delay_handle = std::move(read_delay_handle)]() mutable {
234
+ self->dependency_mgr_->OnClusterError(self->name_, std::move(status));
235
+ },
236
+ DEBUG_LOCATION);
237
+ }
238
+
239
+ void OnResourceDoesNotExist(
240
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
241
+ dependency_mgr_->work_serializer_->Run(
242
+ [self = RefAsSubclass<ClusterWatcher>(),
243
+ read_delay_handle = std::move(read_delay_handle)]() {
244
+ self->dependency_mgr_->OnClusterDoesNotExist(self->name_);
245
+ },
246
+ DEBUG_LOCATION);
247
+ }
248
+
249
+ private:
250
+ RefCountedPtr<XdsDependencyManager> dependency_mgr_;
251
+ std::string name_;
252
+ };
253
+
254
+ //
255
+ // XdsDependencyManager::EndpointWatcher
256
+ //
257
+
258
+ class XdsDependencyManager::EndpointWatcher
259
+ : public XdsEndpointResourceType::WatcherInterface {
260
+ public:
261
+ EndpointWatcher(RefCountedPtr<XdsDependencyManager> dependency_mgr,
262
+ absl::string_view name)
263
+ : dependency_mgr_(std::move(dependency_mgr)), name_(name) {}
264
+
265
+ void OnResourceChanged(
266
+ std::shared_ptr<const XdsEndpointResource> endpoint,
267
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
268
+ dependency_mgr_->work_serializer_->Run(
269
+ [self = RefAsSubclass<EndpointWatcher>(),
270
+ endpoint = std::move(endpoint),
271
+ read_delay_handle = std::move(read_delay_handle)]() mutable {
272
+ self->dependency_mgr_->OnEndpointUpdate(self->name_,
273
+ std::move(endpoint));
274
+ },
275
+ DEBUG_LOCATION);
276
+ }
277
+
278
+ void OnError(
279
+ absl::Status status,
280
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
281
+ dependency_mgr_->work_serializer_->Run(
282
+ [self = RefAsSubclass<EndpointWatcher>(), status = std::move(status),
283
+ read_delay_handle = std::move(read_delay_handle)]() mutable {
284
+ self->dependency_mgr_->OnEndpointError(self->name_,
285
+ std::move(status));
286
+ },
287
+ DEBUG_LOCATION);
288
+ }
289
+
290
+ void OnResourceDoesNotExist(
291
+ RefCountedPtr<XdsClient::ReadDelayHandle> read_delay_handle) override {
292
+ dependency_mgr_->work_serializer_->Run(
293
+ [self = RefAsSubclass<EndpointWatcher>(),
294
+ read_delay_handle = std::move(read_delay_handle)]() {
295
+ self->dependency_mgr_->OnEndpointDoesNotExist(self->name_);
296
+ },
297
+ DEBUG_LOCATION);
298
+ }
299
+
300
+ private:
301
+ RefCountedPtr<XdsDependencyManager> dependency_mgr_;
302
+ std::string name_;
303
+ };
304
+
305
+ //
306
+ // XdsDependencyManager::DnsResultHandler
307
+ //
308
+
309
+ class XdsDependencyManager::DnsResultHandler : public Resolver::ResultHandler {
310
+ public:
311
+ DnsResultHandler(RefCountedPtr<XdsDependencyManager> dependency_mgr,
312
+ std::string name)
313
+ : dependency_mgr_(std::move(dependency_mgr)), name_(std::move(name)) {}
314
+
315
+ void ReportResult(Resolver::Result result) override {
316
+ dependency_mgr_->work_serializer_->Run(
317
+ [dependency_mgr = dependency_mgr_, name = name_,
318
+ result = std::move(result)]() mutable {
319
+ dependency_mgr->OnDnsResult(name, std::move(result));
320
+ },
321
+ DEBUG_LOCATION);
322
+ }
323
+
324
+ private:
325
+ RefCountedPtr<XdsDependencyManager> dependency_mgr_;
326
+ std::string name_;
327
+ };
328
+
329
+ //
330
+ // XdsDependencyManager::ClusterSubscription
331
+ //
332
+
333
+ void XdsDependencyManager::ClusterSubscription::Orphan() {
334
+ dependency_mgr_->work_serializer_->Run(
335
+ [self = WeakRef()]() {
336
+ self->dependency_mgr_->OnClusterSubscriptionUnref(self->cluster_name_,
337
+ self.get());
338
+ },
339
+ DEBUG_LOCATION);
340
+ }
341
+
342
+ //
343
+ // XdsDependencyManager
344
+ //
345
+
346
+ XdsDependencyManager::XdsDependencyManager(
347
+ RefCountedPtr<GrpcXdsClient> xds_client,
348
+ std::shared_ptr<WorkSerializer> work_serializer,
349
+ std::unique_ptr<Watcher> watcher, std::string data_plane_authority,
350
+ std::string listener_resource_name, ChannelArgs args,
351
+ grpc_pollset_set* interested_parties)
352
+ : xds_client_(std::move(xds_client)),
353
+ work_serializer_(std::move(work_serializer)),
354
+ watcher_(std::move(watcher)),
355
+ data_plane_authority_(std::move(data_plane_authority)),
356
+ listener_resource_name_(std::move(listener_resource_name)),
357
+ args_(std::move(args)),
358
+ interested_parties_(interested_parties) {
359
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
360
+ gpr_log(GPR_INFO,
361
+ "[XdsDependencyManager %p] starting watch for listener %s", this,
362
+ listener_resource_name_.c_str());
363
+ }
364
+ auto listener_watcher = MakeRefCounted<ListenerWatcher>(Ref());
365
+ listener_watcher_ = listener_watcher.get();
366
+ XdsListenerResourceType::StartWatch(
367
+ xds_client_.get(), listener_resource_name_, std::move(listener_watcher));
368
+ }
369
+
370
+ void XdsDependencyManager::Orphan() {
371
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
372
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] shutting down", this);
373
+ }
374
+ if (listener_watcher_ != nullptr) {
375
+ XdsListenerResourceType::CancelWatch(
376
+ xds_client_.get(), listener_resource_name_, listener_watcher_,
377
+ /*delay_unsubscription=*/false);
378
+ }
379
+ if (route_config_watcher_ != nullptr) {
380
+ XdsRouteConfigResourceType::CancelWatch(
381
+ xds_client_.get(), route_config_name_, route_config_watcher_,
382
+ /*delay_unsubscription=*/false);
383
+ }
384
+ for (const auto& p : cluster_watchers_) {
385
+ XdsClusterResourceType::CancelWatch(xds_client_.get(), p.first,
386
+ p.second.watcher,
387
+ /*delay_unsubscription=*/false);
388
+ }
389
+ for (const auto& p : endpoint_watchers_) {
390
+ XdsEndpointResourceType::CancelWatch(xds_client_.get(), p.first,
391
+ p.second.watcher,
392
+ /*delay_unsubscription=*/false);
393
+ }
394
+ cluster_subscriptions_.clear();
395
+ xds_client_.reset();
396
+ for (auto& p : dns_resolvers_) {
397
+ p.second.resolver.reset();
398
+ }
399
+ Unref();
400
+ }
401
+
402
+ void XdsDependencyManager::OnListenerUpdate(
403
+ std::shared_ptr<const XdsListenerResource> listener) {
404
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
405
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] received Listener update",
406
+ this);
407
+ }
408
+ if (xds_client_ == nullptr) return;
409
+ const auto* hcm = absl::get_if<XdsListenerResource::HttpConnectionManager>(
410
+ &listener->listener);
411
+ if (hcm == nullptr) {
412
+ return OnError(listener_resource_name_,
413
+ absl::UnavailableError("not an API listener"));
414
+ }
415
+ current_listener_ = std::move(listener);
416
+ Match(
417
+ hcm->route_config,
418
+ // RDS resource name
419
+ [&](const std::string& rds_name) {
420
+ // If the RDS name changed, update the RDS watcher.
421
+ // Note that this will be true on the initial update, because
422
+ // route_config_name_ will be empty.
423
+ if (route_config_name_ != rds_name) {
424
+ // If we already had a watch (i.e., if the previous config had
425
+ // a different RDS name), stop the previous watch.
426
+ // There will be no previous watch if either (a) this is the
427
+ // initial resource update or (b) the previous Listener had an
428
+ // inlined RouteConfig.
429
+ if (route_config_watcher_ != nullptr) {
430
+ XdsRouteConfigResourceType::CancelWatch(
431
+ xds_client_.get(), route_config_name_, route_config_watcher_,
432
+ /*delay_unsubscription=*/true);
433
+ route_config_watcher_ = nullptr;
434
+ }
435
+ // Start watch for the new RDS resource name.
436
+ route_config_name_ = rds_name;
437
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
438
+ gpr_log(
439
+ GPR_INFO,
440
+ "[XdsDependencyManager %p] starting watch for route config %s",
441
+ this, route_config_name_.c_str());
442
+ }
443
+ auto watcher =
444
+ MakeRefCounted<RouteConfigWatcher>(Ref(), route_config_name_);
445
+ route_config_watcher_ = watcher.get();
446
+ XdsRouteConfigResourceType::StartWatch(
447
+ xds_client_.get(), route_config_name_, std::move(watcher));
448
+ } else {
449
+ // RDS resource name has not changed, so no watch needs to be
450
+ // updated, but we still need to propagate any changes in the
451
+ // HCM config (e.g., the list of HTTP filters).
452
+ MaybeReportUpdate();
453
+ }
454
+ },
455
+ // inlined RouteConfig
456
+ [&](const std::shared_ptr<const XdsRouteConfigResource>& route_config) {
457
+ // If the previous update specified an RDS resource instead of
458
+ // having an inlined RouteConfig, we need to cancel the RDS watch.
459
+ if (route_config_watcher_ != nullptr) {
460
+ XdsRouteConfigResourceType::CancelWatch(
461
+ xds_client_.get(), route_config_name_, route_config_watcher_);
462
+ route_config_watcher_ = nullptr;
463
+ route_config_name_.clear();
464
+ }
465
+ OnRouteConfigUpdate("", route_config);
466
+ });
467
+ }
468
+
469
+ namespace {
470
+
471
+ class XdsVirtualHostListIterator : public XdsRouting::VirtualHostListIterator {
472
+ public:
473
+ explicit XdsVirtualHostListIterator(
474
+ const std::vector<XdsRouteConfigResource::VirtualHost>* virtual_hosts)
475
+ : virtual_hosts_(virtual_hosts) {}
476
+
477
+ size_t Size() const override { return virtual_hosts_->size(); }
478
+
479
+ const std::vector<std::string>& GetDomainsForVirtualHost(
480
+ size_t index) const override {
481
+ return (*virtual_hosts_)[index].domains;
482
+ }
483
+
484
+ private:
485
+ const std::vector<XdsRouteConfigResource::VirtualHost>* virtual_hosts_;
486
+ };
487
+
488
+ // Gets the set of clusters referenced in the specified virtual host.
489
+ absl::flat_hash_set<absl::string_view> GetClustersFromVirtualHost(
490
+ const XdsRouteConfigResource::VirtualHost& virtual_host) {
491
+ absl::flat_hash_set<absl::string_view> clusters;
492
+ for (auto& route : virtual_host.routes) {
493
+ auto* route_action =
494
+ absl::get_if<XdsRouteConfigResource::Route::RouteAction>(&route.action);
495
+ if (route_action == nullptr) continue;
496
+ Match(
497
+ route_action->action,
498
+ // cluster name
499
+ [&](const XdsRouteConfigResource::Route::RouteAction::ClusterName&
500
+ cluster_name) { clusters.insert(cluster_name.cluster_name); },
501
+ // WeightedClusters
502
+ [&](const std::vector<
503
+ XdsRouteConfigResource::Route::RouteAction::ClusterWeight>&
504
+ weighted_clusters) {
505
+ for (const auto& weighted_cluster : weighted_clusters) {
506
+ clusters.insert(weighted_cluster.name);
507
+ }
508
+ },
509
+ // ClusterSpecifierPlugin
510
+ [&](const XdsRouteConfigResource::Route::RouteAction::
511
+ ClusterSpecifierPluginName&) {
512
+ // Clusters are determined dynamically in this case, so we
513
+ // can't add any clusters here.
514
+ });
515
+ }
516
+ return clusters;
517
+ }
518
+
519
+ } // namespace
520
+
521
+ void XdsDependencyManager::OnRouteConfigUpdate(
522
+ const std::string& name,
523
+ std::shared_ptr<const XdsRouteConfigResource> route_config) {
524
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
525
+ gpr_log(GPR_INFO,
526
+ "[XdsDependencyManager %p] received RouteConfig update for %s",
527
+ this, name.empty() ? "<inline>" : name.c_str());
528
+ }
529
+ if (xds_client_ == nullptr) return;
530
+ // Ignore updates for stale names.
531
+ if (name.empty()) {
532
+ if (!route_config_name_.empty()) return;
533
+ } else {
534
+ if (name != route_config_name_) return;
535
+ }
536
+ // Find the relevant VirtualHost from the RouteConfiguration.
537
+ // If the resource doesn't have the right vhost, fail without updating
538
+ // our data.
539
+ auto vhost_index = XdsRouting::FindVirtualHostForDomain(
540
+ XdsVirtualHostListIterator(&route_config->virtual_hosts),
541
+ data_plane_authority_);
542
+ if (!vhost_index.has_value()) {
543
+ OnError(route_config_name_.empty() ? listener_resource_name_
544
+ : route_config_name_,
545
+ absl::UnavailableError(
546
+ absl::StrCat("could not find VirtualHost for ",
547
+ data_plane_authority_, " in RouteConfiguration")));
548
+ return;
549
+ }
550
+ // Update our data.
551
+ current_route_config_ = std::move(route_config);
552
+ current_virtual_host_ = &current_route_config_->virtual_hosts[*vhost_index];
553
+ clusters_from_route_config_ =
554
+ GetClustersFromVirtualHost(*current_virtual_host_);
555
+ MaybeReportUpdate();
556
+ }
557
+
558
+ void XdsDependencyManager::OnError(std::string context, absl::Status status) {
559
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
560
+ gpr_log(GPR_INFO,
561
+ "[XdsDependencyManager %p] received Listener or RouteConfig "
562
+ "error: %s %s",
563
+ this, context.c_str(), status.ToString().c_str());
564
+ }
565
+ if (xds_client_ == nullptr) return;
566
+ if (current_virtual_host_ != nullptr) return;
567
+ watcher_->OnError(context, std::move(status));
568
+ }
569
+
570
+ void XdsDependencyManager::OnResourceDoesNotExist(std::string context) {
571
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
572
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] %s", this, context.c_str());
573
+ }
574
+ if (xds_client_ == nullptr) return;
575
+ current_virtual_host_ = nullptr;
576
+ watcher_->OnResourceDoesNotExist(std::move(context));
577
+ }
578
+
579
+ void XdsDependencyManager::OnClusterUpdate(
580
+ const std::string& name,
581
+ std::shared_ptr<const XdsClusterResource> cluster) {
582
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
583
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] received Cluster update: %s",
584
+ this, name.c_str());
585
+ }
586
+ if (xds_client_ == nullptr) return;
587
+ auto it = cluster_watchers_.find(name);
588
+ if (it == cluster_watchers_.end()) return;
589
+ it->second.update = std::move(cluster);
590
+ MaybeReportUpdate();
591
+ }
592
+
593
+ void XdsDependencyManager::OnClusterError(const std::string& name,
594
+ absl::Status status) {
595
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
596
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] received Cluster error: %s %s",
597
+ this, name.c_str(), status.ToString().c_str());
598
+ }
599
+ if (xds_client_ == nullptr) return;
600
+ auto it = cluster_watchers_.find(name);
601
+ if (it == cluster_watchers_.end()) return;
602
+ if (it->second.update.value_or(nullptr) == nullptr) {
603
+ it->second.update =
604
+ absl::Status(status.code(), absl::StrCat(name, ": ", status.message()));
605
+ }
606
+ MaybeReportUpdate();
607
+ }
608
+
609
+ void XdsDependencyManager::OnClusterDoesNotExist(const std::string& name) {
610
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
611
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] Cluster does not exist: %s",
612
+ this, name.c_str());
613
+ }
614
+ if (xds_client_ == nullptr) return;
615
+ auto it = cluster_watchers_.find(name);
616
+ if (it == cluster_watchers_.end()) return;
617
+ it->second.update = absl::UnavailableError(
618
+ absl::StrCat("CDS resource ", name, " does not exist"));
619
+ MaybeReportUpdate();
620
+ }
621
+
622
+ void XdsDependencyManager::OnEndpointUpdate(
623
+ const std::string& name,
624
+ std::shared_ptr<const XdsEndpointResource> endpoint) {
625
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
626
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] received Endpoint update: %s",
627
+ this, name.c_str());
628
+ }
629
+ if (xds_client_ == nullptr) return;
630
+ auto it = endpoint_watchers_.find(name);
631
+ if (it == endpoint_watchers_.end()) return;
632
+ if (endpoint->priorities.empty()) {
633
+ it->second.update.resolution_note =
634
+ absl::StrCat("EDS resource ", name, " contains no localities");
635
+ } else {
636
+ std::set<std::string> empty_localities;
637
+ for (const auto& priority : endpoint->priorities) {
638
+ for (const auto& p : priority.localities) {
639
+ if (p.second.endpoints.empty()) {
640
+ empty_localities.insert(p.first->AsHumanReadableString());
641
+ }
642
+ }
643
+ }
644
+ if (!empty_localities.empty()) {
645
+ it->second.update.resolution_note =
646
+ absl::StrCat("EDS resource ", name, " contains empty localities: [",
647
+ absl::StrJoin(empty_localities, "; "), "]");
648
+ }
649
+ }
650
+ it->second.update.endpoints = std::move(endpoint);
651
+ MaybeReportUpdate();
652
+ }
653
+
654
+ void XdsDependencyManager::OnEndpointError(const std::string& name,
655
+ absl::Status status) {
656
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
657
+ gpr_log(GPR_INFO,
658
+ "[XdsDependencyManager %p] received Endpoint error: %s %s", this,
659
+ name.c_str(), status.ToString().c_str());
660
+ }
661
+ if (xds_client_ == nullptr) return;
662
+ auto it = endpoint_watchers_.find(name);
663
+ if (it == endpoint_watchers_.end()) return;
664
+ if (it->second.update.endpoints == nullptr) {
665
+ it->second.update.resolution_note =
666
+ absl::StrCat("EDS resource ", name, ": ", status.ToString());
667
+ MaybeReportUpdate();
668
+ }
669
+ }
670
+
671
+ void XdsDependencyManager::OnEndpointDoesNotExist(const std::string& name) {
672
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
673
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] Endpoint does not exist: %s",
674
+ this, name.c_str());
675
+ }
676
+ if (xds_client_ == nullptr) return;
677
+ auto it = endpoint_watchers_.find(name);
678
+ if (it == endpoint_watchers_.end()) return;
679
+ it->second.update.endpoints.reset();
680
+ it->second.update.resolution_note =
681
+ absl::StrCat("EDS resource ", name, " does not exist");
682
+ MaybeReportUpdate();
683
+ }
684
+
685
+ void XdsDependencyManager::OnDnsResult(const std::string& dns_name,
686
+ Resolver::Result result) {
687
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
688
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] received DNS update: %s", this,
689
+ dns_name.c_str());
690
+ }
691
+ if (xds_client_ == nullptr) return;
692
+ auto it = dns_resolvers_.find(dns_name);
693
+ if (it == dns_resolvers_.end()) return;
694
+ PopulateDnsUpdate(dns_name, std::move(result), &it->second);
695
+ MaybeReportUpdate();
696
+ }
697
+
698
+ void XdsDependencyManager::PopulateDnsUpdate(const std::string& dns_name,
699
+ Resolver::Result result,
700
+ DnsState* dns_state) {
701
+ // Convert resolver result to EDS update.
702
+ XdsEndpointResource::Priority::Locality locality;
703
+ locality.name = MakeRefCounted<XdsLocalityName>("", "", "");
704
+ locality.lb_weight = 1;
705
+ if (result.addresses.ok()) {
706
+ locality.endpoints = std::move(*result.addresses);
707
+ dns_state->update.resolution_note = std::move(result.resolution_note);
708
+ } else if (result.resolution_note.empty()) {
709
+ dns_state->update.resolution_note =
710
+ absl::StrCat("DNS resolution failed for ", dns_name, ": ",
711
+ result.addresses.status().ToString());
712
+ }
713
+ XdsEndpointResource::Priority priority;
714
+ priority.localities.emplace(locality.name.get(), std::move(locality));
715
+ auto resource = std::make_shared<XdsEndpointResource>();
716
+ resource->priorities.emplace_back(std::move(priority));
717
+ dns_state->update.endpoints = std::move(resource);
718
+ }
719
+
720
+ bool XdsDependencyManager::PopulateClusterConfigMap(
721
+ absl::string_view name, int depth,
722
+ absl::flat_hash_map<std::string, absl::StatusOr<XdsConfig::ClusterConfig>>*
723
+ cluster_config_map,
724
+ std::set<absl::string_view>* eds_resources_seen,
725
+ std::set<absl::string_view>* dns_names_seen,
726
+ absl::StatusOr<std::vector<absl::string_view>>* leaf_clusters) {
727
+ if (depth > 0) GPR_ASSERT(leaf_clusters != nullptr);
728
+ if (depth == kMaxXdsAggregateClusterRecursionDepth) {
729
+ *leaf_clusters =
730
+ absl::UnavailableError("aggregate cluster graph exceeds max depth");
731
+ return true;
732
+ }
733
+ // Don't process the cluster again if we've already seen it in some
734
+ // other branch of the recursion tree. We populate it with a non-OK
735
+ // status here, since we need an entry in the map to avoid incorrectly
736
+ // stopping the CDS watch, but we'll overwrite this below if we actually
737
+ // have the data for the cluster.
738
+ auto p = cluster_config_map->emplace(
739
+ name, absl::InternalError("cluster data not yet available"));
740
+ if (!p.second) return true;
741
+ auto& cluster_config = p.first->second;
742
+ auto& state = cluster_watchers_[name];
743
+ // Create a new watcher if needed.
744
+ if (state.watcher == nullptr) {
745
+ auto watcher = MakeRefCounted<ClusterWatcher>(Ref(), name);
746
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
747
+ gpr_log(GPR_INFO,
748
+ "[XdsDependencyManager %p] starting watch for cluster %s", this,
749
+ std::string(name).c_str());
750
+ }
751
+ state.watcher = watcher.get();
752
+ XdsClusterResourceType::StartWatch(xds_client_.get(), name,
753
+ std::move(watcher));
754
+ return false;
755
+ }
756
+ // If there was an error fetching the CDS resource, report the error.
757
+ if (!state.update.ok()) {
758
+ cluster_config = state.update.status();
759
+ return true;
760
+ }
761
+ // If we don't have the resource yet, we can't return a config yet.
762
+ if (*state.update == nullptr) return false;
763
+ // Populate endpoint info based on cluster type.
764
+ return Match(
765
+ (*state.update)->type,
766
+ // EDS cluster.
767
+ [&](const XdsClusterResource::Eds& eds) {
768
+ absl::string_view eds_resource_name =
769
+ eds.eds_service_name.empty() ? name : eds.eds_service_name;
770
+ eds_resources_seen->insert(eds_resource_name);
771
+ // Start EDS watch if needed.
772
+ auto& eds_state = endpoint_watchers_[eds_resource_name];
773
+ if (eds_state.watcher == nullptr) {
774
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
775
+ gpr_log(GPR_INFO,
776
+ "[XdsDependencyManager %p] starting watch for endpoint %s",
777
+ this, std::string(eds_resource_name).c_str());
778
+ }
779
+ auto watcher =
780
+ MakeRefCounted<EndpointWatcher>(Ref(), eds_resource_name);
781
+ eds_state.watcher = watcher.get();
782
+ XdsEndpointResourceType::StartWatch(
783
+ xds_client_.get(), eds_resource_name, std::move(watcher));
784
+ return false;
785
+ }
786
+ // Check if EDS resource has been returned.
787
+ if (eds_state.update.endpoints == nullptr &&
788
+ eds_state.update.resolution_note.empty()) {
789
+ return false;
790
+ }
791
+ // Populate cluster config.
792
+ cluster_config.emplace(*state.update, eds_state.update.endpoints,
793
+ eds_state.update.resolution_note);
794
+ if (leaf_clusters != nullptr) (*leaf_clusters)->push_back(name);
795
+ return true;
796
+ },
797
+ // LOGICAL_DNS cluster.
798
+ [&](const XdsClusterResource::LogicalDns& logical_dns) {
799
+ dns_names_seen->insert(logical_dns.hostname);
800
+ // Start DNS resolver if needed.
801
+ auto& dns_state = dns_resolvers_[logical_dns.hostname];
802
+ if (dns_state.resolver == nullptr) {
803
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
804
+ gpr_log(GPR_INFO,
805
+ "[XdsDependencyManager %p] starting DNS resolver for %s",
806
+ this, logical_dns.hostname.c_str());
807
+ }
808
+ auto* fake_resolver_response_generator = args_.GetPointer<
809
+ FakeResolverResponseGenerator>(
810
+ GRPC_ARG_XDS_LOGICAL_DNS_CLUSTER_FAKE_RESOLVER_RESPONSE_GENERATOR);
811
+ ChannelArgs args = args_;
812
+ std::string target;
813
+ if (fake_resolver_response_generator != nullptr) {
814
+ target = absl::StrCat("fake:", logical_dns.hostname);
815
+ args = args.SetObject(fake_resolver_response_generator->Ref());
816
+ } else {
817
+ target = absl::StrCat("dns:", logical_dns.hostname);
818
+ }
819
+ dns_state.resolver =
820
+ CoreConfiguration::Get().resolver_registry().CreateResolver(
821
+ target, args, interested_parties_, work_serializer_,
822
+ std::make_unique<DnsResultHandler>(Ref(),
823
+ logical_dns.hostname));
824
+ if (dns_state.resolver == nullptr) {
825
+ Resolver::Result result;
826
+ result.addresses.emplace(); // Empty list.
827
+ result.resolution_note = absl::StrCat(
828
+ "failed to create DNS resolver for ", logical_dns.hostname);
829
+ PopulateDnsUpdate(logical_dns.hostname, std::move(result),
830
+ &dns_state);
831
+ } else {
832
+ dns_state.resolver->StartLocked();
833
+ return false;
834
+ }
835
+ }
836
+ // Check if result has been returned.
837
+ if (dns_state.update.endpoints == nullptr &&
838
+ dns_state.update.resolution_note.empty()) {
839
+ return false;
840
+ }
841
+ // Populate cluster config.
842
+ cluster_config.emplace(*state.update, dns_state.update.endpoints,
843
+ dns_state.update.resolution_note);
844
+ if (leaf_clusters != nullptr) (*leaf_clusters)->push_back(name);
845
+ return true;
846
+ },
847
+ // Aggregate cluster. Recursively expand to child clusters.
848
+ [&](const XdsClusterResource::Aggregate& aggregate) {
849
+ // Grab a ref to the CDS resource for the aggregate cluster here,
850
+ // since our reference into cluster_watchers_ will be invalidated
851
+ // when we recursively call ourselves and add entries to the
852
+ // map for underlying clusters.
853
+ auto cluster_resource = *state.update;
854
+ // Recursively expand leaf clusters.
855
+ absl::StatusOr<std::vector<absl::string_view>> child_leaf_clusters;
856
+ child_leaf_clusters.emplace();
857
+ bool have_all_resources = true;
858
+ for (const std::string& child_name :
859
+ aggregate.prioritized_cluster_names) {
860
+ have_all_resources &= PopulateClusterConfigMap(
861
+ child_name, depth + 1, cluster_config_map, eds_resources_seen,
862
+ dns_names_seen, &child_leaf_clusters);
863
+ if (!child_leaf_clusters.ok()) break;
864
+ }
865
+ // Note that we cannot use the cluster_config reference we
866
+ // created above, because it may have been invalidated by map
867
+ // insertions when we recursively called ourselves, so we have
868
+ // to do the lookup in cluster_config_map again.
869
+ auto& aggregate_cluster_config = (*cluster_config_map)[name];
870
+ // If we exceeded max recursion depth, report an error for the
871
+ // cluster, and propagate the error up if needed.
872
+ if (!child_leaf_clusters.ok()) {
873
+ aggregate_cluster_config = child_leaf_clusters.status();
874
+ if (leaf_clusters != nullptr) {
875
+ *leaf_clusters = child_leaf_clusters.status();
876
+ }
877
+ return true;
878
+ }
879
+ // If needed, propagate leaf cluster list up the tree.
880
+ if (leaf_clusters != nullptr) {
881
+ (*leaf_clusters)
882
+ ->insert((*leaf_clusters)->end(), child_leaf_clusters->begin(),
883
+ child_leaf_clusters->end());
884
+ }
885
+ // If there are no leaf clusters, report an error for the cluster.
886
+ if (have_all_resources && child_leaf_clusters->empty()) {
887
+ aggregate_cluster_config = absl::UnavailableError(
888
+ absl::StrCat("aggregate cluster dependency graph for ", name,
889
+ " has no leaf clusters"));
890
+ return true;
891
+ }
892
+ // Populate cluster config.
893
+ // Note that we do this even for aggregate clusters that are not
894
+ // at the root of the tree, because we need to make sure the list
895
+ // of underlying cluster names stays alive so that the leaf cluster
896
+ // list of the root aggregate cluster can point to those strings.
897
+ aggregate_cluster_config.emplace(std::move(cluster_resource),
898
+ std::move(*child_leaf_clusters));
899
+ return have_all_resources;
900
+ });
901
+ }
902
+
903
+ RefCountedPtr<XdsDependencyManager::ClusterSubscription>
904
+ XdsDependencyManager::GetClusterSubscription(absl::string_view cluster_name) {
905
+ auto it = cluster_subscriptions_.find(cluster_name);
906
+ if (it != cluster_subscriptions_.end()) {
907
+ auto subscription = it->second->RefIfNonZero();
908
+ if (subscription != nullptr) return subscription;
909
+ }
910
+ auto subscription = MakeRefCounted<ClusterSubscription>(cluster_name, Ref());
911
+ cluster_subscriptions_.emplace(subscription->cluster_name(),
912
+ subscription->WeakRef());
913
+ // If the cluster is not already subscribed to by virtue of being
914
+ // referenced in the route config, then trigger the CDS watch.
915
+ if (!clusters_from_route_config_.contains(cluster_name)) {
916
+ MaybeReportUpdate();
917
+ }
918
+ return subscription;
919
+ }
920
+
921
+ void XdsDependencyManager::OnClusterSubscriptionUnref(
922
+ absl::string_view cluster_name, ClusterSubscription* subscription) {
923
+ auto it = cluster_subscriptions_.find(cluster_name);
924
+ // Shouldn't happen, but ignore if it does.
925
+ if (it == cluster_subscriptions_.end()) return;
926
+ // Do nothing if the subscription has already been replaced.
927
+ if (it->second != subscription) return;
928
+ // Remove the entry.
929
+ cluster_subscriptions_.erase(it);
930
+ // If this cluster is not already subscribed to by virtue of being
931
+ // referenced in the route config, then update watches and generate a
932
+ // new update.
933
+ if (!clusters_from_route_config_.contains(cluster_name)) {
934
+ MaybeReportUpdate();
935
+ }
936
+ }
937
+
938
+ void XdsDependencyManager::MaybeReportUpdate() {
939
+ // Populate Listener and RouteConfig fields.
940
+ if (current_virtual_host_ == nullptr) return;
941
+ auto config = MakeRefCounted<XdsConfig>();
942
+ config->listener = current_listener_;
943
+ config->route_config = current_route_config_;
944
+ config->virtual_host = current_virtual_host_;
945
+ // Determine the set of clusters we should be watching.
946
+ std::set<absl::string_view> clusters_to_watch;
947
+ for (const absl::string_view& cluster : clusters_from_route_config_) {
948
+ clusters_to_watch.insert(cluster);
949
+ }
950
+ for (const auto& p : cluster_subscriptions_) {
951
+ clusters_to_watch.insert(p.first);
952
+ }
953
+ // Populate Cluster map.
954
+ // We traverse the entire graph even if we don't yet have all of the
955
+ // resources we need to ensure that the right set of watches are active.
956
+ std::set<absl::string_view> eds_resources_seen;
957
+ std::set<absl::string_view> dns_names_seen;
958
+ bool have_all_resources = true;
959
+ for (const absl::string_view& cluster : clusters_to_watch) {
960
+ have_all_resources &= PopulateClusterConfigMap(
961
+ cluster, 0, &config->clusters, &eds_resources_seen, &dns_names_seen);
962
+ }
963
+ // Remove entries in cluster_watchers_ for any clusters not in
964
+ // config->clusters.
965
+ for (auto it = cluster_watchers_.begin(); it != cluster_watchers_.end();) {
966
+ const std::string& cluster_name = it->first;
967
+ if (config->clusters.contains(cluster_name)) {
968
+ ++it;
969
+ continue;
970
+ }
971
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
972
+ gpr_log(GPR_INFO,
973
+ "[XdsDependencyManager %p] cancelling watch for cluster %s", this,
974
+ cluster_name.c_str());
975
+ }
976
+ XdsClusterResourceType::CancelWatch(xds_client_.get(), cluster_name,
977
+ it->second.watcher,
978
+ /*delay_unsubscription=*/false);
979
+ cluster_watchers_.erase(it++);
980
+ }
981
+ // Remove entries in endpoint_watchers_ for any EDS resources not in
982
+ // eds_resources_seen.
983
+ for (auto it = endpoint_watchers_.begin(); it != endpoint_watchers_.end();) {
984
+ const std::string& eds_resource_name = it->first;
985
+ if (eds_resources_seen.find(eds_resource_name) !=
986
+ eds_resources_seen.end()) {
987
+ ++it;
988
+ continue;
989
+ }
990
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
991
+ gpr_log(GPR_INFO,
992
+ "[XdsDependencyManager %p] cancelling watch for EDS resource %s",
993
+ this, eds_resource_name.c_str());
994
+ }
995
+ XdsEndpointResourceType::CancelWatch(xds_client_.get(), eds_resource_name,
996
+ it->second.watcher,
997
+ /*delay_unsubscription=*/false);
998
+ endpoint_watchers_.erase(it++);
999
+ }
1000
+ // Remove entries in dns_resolvers_ for any DNS name not in
1001
+ // eds_resources_seen.
1002
+ for (auto it = dns_resolvers_.begin(); it != dns_resolvers_.end();) {
1003
+ const std::string& dns_name = it->first;
1004
+ if (dns_names_seen.find(dns_name) != dns_names_seen.end()) {
1005
+ ++it;
1006
+ continue;
1007
+ }
1008
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
1009
+ gpr_log(GPR_INFO,
1010
+ "[XdsDependencyManager %p] shutting down DNS resolver for %s",
1011
+ this, dns_name.c_str());
1012
+ }
1013
+ dns_resolvers_.erase(it++);
1014
+ }
1015
+ // If we have all the data we need, then send an update.
1016
+ if (!have_all_resources) {
1017
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
1018
+ gpr_log(GPR_INFO,
1019
+ "[XdsDependencyManager %p] missing data -- NOT returning config",
1020
+ this);
1021
+ }
1022
+ return;
1023
+ }
1024
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
1025
+ gpr_log(GPR_INFO, "[XdsDependencyManager %p] returning config: %s", this,
1026
+ config->ToString().c_str());
1027
+ }
1028
+ watcher_->OnUpdate(std::move(config));
1029
+ }
1030
+
1031
+ } // namespace grpc_core