diff --git a/BUILD b/BUILD index b3c97ca5e2a..4fc1091b635 100644 --- a/BUILD +++ b/BUILD @@ -956,6 +956,7 @@ grpc_cc_library( external_deps = [ "madler_zlib", "absl/container:inlined_vector", + "absl/status", "absl/types:optional", ], language = "c++", diff --git a/BUILD.gn b/BUILD.gn index 035d6bddde6..b38ffc2301b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -991,6 +991,7 @@ config("grpc_config") { ":upb", ":absl/types:optional", ":absl/strings:strings", + ":absl/status:status", ":absl/container:inlined_vector", "//third_party/cares", ":address_sorting", diff --git a/CMakeLists.txt b/CMakeLists.txt index ce8a7e338c0..d7fb543e242 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,23 +111,32 @@ set(gRPC_ABSL_USED_TARGETS absl_civil_time absl_compressed_tuple absl_config + absl_cord absl_core_headers + absl_debugging_internal + absl_demangle_internal absl_dynamic_annotations absl_endian absl_errno_saver + absl_fixed_array + absl_function_ref absl_inlined_vector absl_inlined_vector_internal absl_int128 absl_log_severity + absl_malloc_internal absl_memory absl_optional absl_raw_logging_internal absl_span absl_spinlock_wait + absl_stacktrace + absl_status absl_str_format absl_str_format_internal absl_strings absl_strings_internal + absl_symbolize absl_throw_delegate absl_time absl_time_zone @@ -1793,6 +1802,7 @@ target_link_libraries(grpc upb absl::optional absl::strings + absl::status absl::inlined_vector ) if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) @@ -2395,6 +2405,7 @@ target_link_libraries(grpc_unsecure upb absl::optional absl::strings + absl::status absl::inlined_vector ) if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) @@ -15546,7 +15557,7 @@ generate_pkgconfig( "high performance general RPC framework" "${gRPC_CORE_VERSION}" "gpr openssl" - "-lgrpc -laddress_sorting -lre2 -lupb -lcares -lz -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations" + "-lgrpc -laddress_sorting -lre2 -lupb -lcares -lz -labsl_status -labsl_cord -labsl_symbolize -labsl_demangle_internal -labsl_malloc_internal -labsl_stacktrace -labsl_debugging_internal -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations" "" "grpc.pc") @@ -15556,7 +15567,7 @@ generate_pkgconfig( "high performance general RPC framework without SSL" "${gRPC_CORE_VERSION}" "gpr" - "-lgrpc_unsecure -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations" + "-lgrpc_unsecure -labsl_status -labsl_cord -labsl_symbolize -labsl_demangle_internal -labsl_malloc_internal -labsl_stacktrace -labsl_debugging_internal -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations" "" "grpc_unsecure.pc") @@ -15566,7 +15577,7 @@ generate_pkgconfig( "C++ wrapper for gRPC" "${gRPC_CPP_VERSION}" "grpc" - "-lgrpc++ -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations" + "-lgrpc++ -labsl_status -labsl_cord -labsl_symbolize -labsl_demangle_internal -labsl_malloc_internal -labsl_stacktrace -labsl_debugging_internal -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations" "" "grpc++.pc") @@ -15576,6 +15587,6 @@ generate_pkgconfig( "C++ wrapper for gRPC without SSL" "${gRPC_CPP_VERSION}" "grpc_unsecure" - "-lgrpc++_unsecure -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations" + "-lgrpc++_unsecure -labsl_status -labsl_cord -labsl_symbolize -labsl_demangle_internal -labsl_malloc_internal -labsl_stacktrace -labsl_debugging_internal -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations" "" "grpc++_unsecure.pc") diff --git a/Makefile b/Makefile index b86df824e22..fcb70c554dc 100644 --- a/Makefile +++ b/Makefile @@ -6236,6 +6236,7 @@ endif LIBGRPC_ABSEIL_SRC = \ third_party/abseil-cpp/absl/base/dynamic_annotations.cc \ third_party/abseil-cpp/absl/base/internal/cycleclock.cc \ + third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc \ third_party/abseil-cpp/absl/base/internal/raw_logging.cc \ third_party/abseil-cpp/absl/base/internal/spinlock.cc \ third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc \ @@ -6244,9 +6245,18 @@ LIBGRPC_ABSEIL_SRC = \ third_party/abseil-cpp/absl/base/internal/throw_delegate.cc \ third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc \ third_party/abseil-cpp/absl/base/log_severity.cc \ + third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc \ + third_party/abseil-cpp/absl/debugging/internal/demangle.cc \ + third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc \ + third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc \ + third_party/abseil-cpp/absl/debugging/stacktrace.cc \ + third_party/abseil-cpp/absl/debugging/symbolize.cc \ third_party/abseil-cpp/absl/numeric/int128.cc \ + third_party/abseil-cpp/absl/status/status.cc \ + third_party/abseil-cpp/absl/status/status_payload_printer.cc \ third_party/abseil-cpp/absl/strings/ascii.cc \ third_party/abseil-cpp/absl/strings/charconv.cc \ + third_party/abseil-cpp/absl/strings/cord.cc \ third_party/abseil-cpp/absl/strings/escaping.cc \ third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc \ third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc \ diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 23a3e3c0554..8720ff88b96 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -1163,6 +1163,7 @@ libs: - upb - absl/types:optional - absl/strings:strings + - absl/status:status - absl/container:inlined_vector baselib: true deps_linkage: static @@ -1952,6 +1953,7 @@ libs: - upb - absl/types:optional - absl/strings:strings + - absl/status:status - absl/container:inlined_vector baselib: true deps_linkage: static diff --git a/config.m4 b/config.m4 index 8cf43fc8a52..bc75131dc70 100644 --- a/config.m4 +++ b/config.m4 @@ -509,6 +509,7 @@ if test "$PHP_GRPC" != "no"; then src/php/ext/grpc/timeval.c \ third_party/abseil-cpp/absl/base/dynamic_annotations.cc \ third_party/abseil-cpp/absl/base/internal/cycleclock.cc \ + third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc \ third_party/abseil-cpp/absl/base/internal/raw_logging.cc \ third_party/abseil-cpp/absl/base/internal/spinlock.cc \ third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc \ @@ -517,9 +518,18 @@ if test "$PHP_GRPC" != "no"; then third_party/abseil-cpp/absl/base/internal/throw_delegate.cc \ third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc \ third_party/abseil-cpp/absl/base/log_severity.cc \ + third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc \ + third_party/abseil-cpp/absl/debugging/internal/demangle.cc \ + third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc \ + third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc \ + third_party/abseil-cpp/absl/debugging/stacktrace.cc \ + third_party/abseil-cpp/absl/debugging/symbolize.cc \ third_party/abseil-cpp/absl/numeric/int128.cc \ + third_party/abseil-cpp/absl/status/status.cc \ + third_party/abseil-cpp/absl/status/status_payload_printer.cc \ third_party/abseil-cpp/absl/strings/ascii.cc \ third_party/abseil-cpp/absl/strings/charconv.cc \ + third_party/abseil-cpp/absl/strings/cord.cc \ third_party/abseil-cpp/absl/strings/escaping.cc \ third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc \ third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc \ @@ -971,7 +981,10 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc) PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/base) PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/base/internal) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/debugging) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/debugging/internal) PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/numeric) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/status) PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/strings) PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/strings/internal) PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/strings/internal/str_format) diff --git a/config.w32 b/config.w32 index 8f027adf682..de58a2c5bea 100644 --- a/config.w32 +++ b/config.w32 @@ -477,6 +477,7 @@ if (PHP_GRPC != "no") { "src\\php\\ext\\grpc\\timeval.c " + "third_party\\abseil-cpp\\absl\\base\\dynamic_annotations.cc " + "third_party\\abseil-cpp\\absl\\base\\internal\\cycleclock.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\low_level_alloc.cc " + "third_party\\abseil-cpp\\absl\\base\\internal\\raw_logging.cc " + "third_party\\abseil-cpp\\absl\\base\\internal\\spinlock.cc " + "third_party\\abseil-cpp\\absl\\base\\internal\\spinlock_wait.cc " + @@ -485,9 +486,18 @@ if (PHP_GRPC != "no") { "third_party\\abseil-cpp\\absl\\base\\internal\\throw_delegate.cc " + "third_party\\abseil-cpp\\absl\\base\\internal\\unscaledcycleclock.cc " + "third_party\\abseil-cpp\\absl\\base\\log_severity.cc " + + "third_party\\abseil-cpp\\absl\\debugging\\internal\\address_is_readable.cc " + + "third_party\\abseil-cpp\\absl\\debugging\\internal\\demangle.cc " + + "third_party\\abseil-cpp\\absl\\debugging\\internal\\elf_mem_image.cc " + + "third_party\\abseil-cpp\\absl\\debugging\\internal\\vdso_support.cc " + + "third_party\\abseil-cpp\\absl\\debugging\\stacktrace.cc " + + "third_party\\abseil-cpp\\absl\\debugging\\symbolize.cc " + "third_party\\abseil-cpp\\absl\\numeric\\int128.cc " + + "third_party\\abseil-cpp\\absl\\status\\status.cc " + + "third_party\\abseil-cpp\\absl\\status\\status_payload_printer.cc " + "third_party\\abseil-cpp\\absl\\strings\\ascii.cc " + "third_party\\abseil-cpp\\absl\\strings\\charconv.cc " + + "third_party\\abseil-cpp\\absl\\strings\\cord.cc " + "third_party\\abseil-cpp\\absl\\strings\\escaping.cc " + "third_party\\abseil-cpp\\absl\\strings\\internal\\charconv_bigint.cc " + "third_party\\abseil-cpp\\absl\\strings\\internal\\charconv_parse.cc " + @@ -1007,7 +1017,10 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\base"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\base\\internal"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\debugging"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\debugging\\internal"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\numeric"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\status"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\strings"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\strings\\internal"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\strings\\internal\\str_format"); diff --git a/doc/python/sphinx/grpc.rst b/doc/python/sphinx/grpc.rst index 4717eb12332..819e2e2f9e4 100644 --- a/doc/python/sphinx/grpc.rst +++ b/doc/python/sphinx/grpc.rst @@ -41,6 +41,7 @@ Create Client Credentials .. autofunction:: composite_call_credentials .. autofunction:: composite_channel_credentials .. autofunction:: local_channel_credentials(local_connect_type=grpc.LocalConnectionType.LOCAL_TCP) +.. autofunction:: compute_engine_channel_credentials Create Server diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a0844acf9a9..c74f5fa8e95 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -210,6 +210,7 @@ Pod::Spec.new do |s| abseil_version = '1.20200225.0' ss.dependency 'abseil/container/inlined_vector', abseil_version ss.dependency 'abseil/memory/memory', abseil_version + ss.dependency 'abseil/status/status', abseil_version ss.dependency 'abseil/strings/str_format', abseil_version ss.dependency 'abseil/strings/strings', abseil_version ss.dependency 'abseil/time/time', abseil_version diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 9ac673e2c3d..869def405bb 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -176,6 +176,7 @@ Pod::Spec.new do |s| abseil_version = '1.20200225.0' ss.dependency 'abseil/container/inlined_vector', abseil_version ss.dependency 'abseil/memory/memory', abseil_version + ss.dependency 'abseil/status/status', abseil_version ss.dependency 'abseil/strings/str_format', abseil_version ss.dependency 'abseil/strings/strings', abseil_version ss.dependency 'abseil/time/time', abseil_version diff --git a/grpc.def b/grpc.def index ad0dca2f0d4..e451ad5bc1d 100644 --- a/grpc.def +++ b/grpc.def @@ -97,12 +97,12 @@ EXPORTS grpc_ssl_session_cache_create_lru grpc_ssl_session_cache_destroy grpc_ssl_session_cache_create_channel_arg + grpc_call_credentials_release grpc_channel_credentials_release grpc_google_default_credentials_create grpc_set_ssl_roots_override_callback grpc_ssl_credentials_create grpc_ssl_credentials_create_ex - grpc_call_credentials_release grpc_composite_channel_credentials_create grpc_composite_call_credentials_create grpc_google_compute_engine_credentials_create diff --git a/grpc.gemspec b/grpc.gemspec index 5b84d4ecf26..157b8dc766c 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -969,12 +969,15 @@ Gem::Specification.new do |s| s.files += %w( third_party/abseil-cpp/absl/base/internal/bits.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/cycleclock.cc ) s.files += %w( third_party/abseil-cpp/absl/base/internal/cycleclock.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/direct_mmap.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/endian.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/errno_saver.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/hide_ptr.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/identity.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/inline_variable.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/invoke.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/low_level_alloc.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/per_thread_tls.h ) s.files += %w( third_party/abseil-cpp/absl/base/internal/raw_logging.cc ) @@ -1007,19 +1010,52 @@ Gem::Specification.new do |s| s.files += %w( third_party/abseil-cpp/absl/base/policy_checks.h ) s.files += %w( third_party/abseil-cpp/absl/base/port.h ) s.files += %w( third_party/abseil-cpp/absl/base/thread_annotations.h ) + s.files += %w( third_party/abseil-cpp/absl/container/fixed_array.h ) s.files += %w( third_party/abseil-cpp/absl/container/inlined_vector.h ) s.files += %w( third_party/abseil-cpp/absl/container/internal/compressed_tuple.h ) s.files += %w( third_party/abseil-cpp/absl/container/internal/inlined_vector.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/address_is_readable.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/demangle.cc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/demangle.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/symbolize.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/internal/vdso_support.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/stacktrace.cc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/stacktrace.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize.cc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize.h ) + s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize_elf.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc ) + s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize_win32.inc ) + s.files += %w( third_party/abseil-cpp/absl/functional/function_ref.h ) + s.files += %w( third_party/abseil-cpp/absl/functional/internal/function_ref.h ) s.files += %w( third_party/abseil-cpp/absl/memory/memory.h ) s.files += %w( third_party/abseil-cpp/absl/meta/type_traits.h ) s.files += %w( third_party/abseil-cpp/absl/numeric/int128.cc ) s.files += %w( third_party/abseil-cpp/absl/numeric/int128.h ) s.files += %w( third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc ) s.files += %w( third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc ) + s.files += %w( third_party/abseil-cpp/absl/status/status.cc ) + s.files += %w( third_party/abseil-cpp/absl/status/status.h ) + s.files += %w( third_party/abseil-cpp/absl/status/status_payload_printer.cc ) + s.files += %w( third_party/abseil-cpp/absl/status/status_payload_printer.h ) s.files += %w( third_party/abseil-cpp/absl/strings/ascii.cc ) s.files += %w( third_party/abseil-cpp/absl/strings/ascii.h ) s.files += %w( third_party/abseil-cpp/absl/strings/charconv.cc ) s.files += %w( third_party/abseil-cpp/absl/strings/charconv.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/cord.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/cord.h ) s.files += %w( third_party/abseil-cpp/absl/strings/escaping.cc ) s.files += %w( third_party/abseil-cpp/absl/strings/escaping.h ) s.files += %w( third_party/abseil-cpp/absl/strings/internal/char_map.h ) @@ -1027,6 +1063,7 @@ Gem::Specification.new do |s| s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h ) s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc ) s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_parse.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/cord_internal.h ) s.files += %w( third_party/abseil-cpp/absl/strings/internal/escaping.cc ) s.files += %w( third_party/abseil-cpp/absl/strings/internal/escaping.h ) s.files += %w( third_party/abseil-cpp/absl/strings/internal/memutil.cc ) diff --git a/grpc.gyp b/grpc.gyp index a7cae5e3f8b..f0ff7c76d25 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -432,6 +432,7 @@ 'upb', 'absl/types:optional', 'absl/strings:strings', + 'absl/status:status', 'absl/container:inlined_vector', ], 'sources': [ @@ -941,6 +942,7 @@ 'upb', 'absl/types:optional', 'absl/strings:strings', + 'absl/status:status', 'absl/container:inlined_vector', ], 'sources': [ diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 99635ea8807..3ff2e8de2cd 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -119,6 +119,18 @@ GRPCAPI void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache); GRPCAPI grpc_arg grpc_ssl_session_cache_create_channel_arg(grpc_ssl_session_cache* cache); +/** --- grpc_call_credentials object. + + A call credentials object represents a way to authenticate on a particular + call. These credentials can be composed with a channel credentials object + so that they are sent with every call on this channel. */ + +typedef struct grpc_call_credentials grpc_call_credentials; + +/** Releases a call credentials object. + The creator of the credentials object is responsible for its release. */ +GRPCAPI void grpc_call_credentials_release(grpc_call_credentials* creds); + /** --- grpc_channel_credentials object. --- A channel credentials object represents a way to authenticate a client on a @@ -133,8 +145,23 @@ GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials* creds); /** Creates default credentials to connect to a google gRPC service. WARNING: Do NOT use this credentials to connect to a non-google service as this could result in an oauth2 token leak. The security level of the - resulting connection is GRPC_PRIVACY_AND_INTEGRITY. */ -GRPCAPI grpc_channel_credentials* grpc_google_default_credentials_create(void); + resulting connection is GRPC_PRIVACY_AND_INTEGRITY. + + If specified, the supplied call credentials object will be attached to the + returned channel credentials object. The call_credentials object must remain + valid throughout the lifetime of the returned grpc_channel_credentials + object. It is expected that the call credentials object was generated + according to the Application Default Credentials mechanism and asserts the + identity of the default service account of the machine. Supplying any other + sort of call credential will result in undefined behavior, up to and + including the sudden and unexpected failure of RPCs. + + If nullptr is supplied, the returned channel credentials object will use a + call credentials object based on the Application Default Credentials + mechanism. +*/ +GRPCAPI grpc_channel_credentials* grpc_google_default_credentials_create( + grpc_call_credentials* call_credentials); /** Callback for getting the SSL roots override from the application. In case of success, *pem_roots_certs must be set to a NULL terminated string @@ -272,24 +299,14 @@ GRPCAPI grpc_channel_credentials* grpc_ssl_credentials_create_ex( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const grpc_ssl_verify_peer_options* verify_options, void* reserved); -/** --- grpc_call_credentials object. - - A call credentials object represents a way to authenticate on a particular - call. These credentials can be composed with a channel credentials object - so that they are sent with every call on this channel. */ - -typedef struct grpc_call_credentials grpc_call_credentials; - -/** Releases a call credentials object. - The creator of the credentials object is responsible for its release. */ -GRPCAPI void grpc_call_credentials_release(grpc_call_credentials* creds); - /** Creates a composite channel credentials object. The security level of * resulting connection is determined by channel_creds. */ GRPCAPI grpc_channel_credentials* grpc_composite_channel_credentials_create( grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds, void* reserved); +/** --- composite credentials. */ + /** Creates a composite call credentials object. */ GRPCAPI grpc_call_credentials* grpc_composite_call_credentials_create( grpc_call_credentials* creds1, grpc_call_credentials* creds2, diff --git a/package.xml b/package.xml index 36399edc3e1..2d755e4d7dc 100644 --- a/package.xml +++ b/package.xml @@ -971,12 +971,15 @@ + + + @@ -1009,19 +1012,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1029,6 +1065,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 2028c8ebb99..1b48d6a4d37 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -214,7 +214,8 @@ class ChannelData { grpc_closure* on_complete, bool cancel); - void Notify(grpc_connectivity_state state) override; + void Notify(grpc_connectivity_state state, + const absl::Status& /* status */) override; void Cancel(); @@ -260,7 +261,8 @@ class ChannelData { ~ChannelData(); void UpdateStateAndPickerLocked( - grpc_connectivity_state state, const char* reason, + grpc_connectivity_state state, const absl::Status& status, + const char* reason, std::unique_ptr picker); void UpdateServiceConfigInDataPlaneLocked( @@ -1212,7 +1214,7 @@ void ChannelData::ExternalConnectivityWatcher:: } void ChannelData::ExternalConnectivityWatcher::Notify( - grpc_connectivity_state state) { + grpc_connectivity_state state, const absl::Status& /* status */) { bool done = false; if (!done_.CompareExchangeStrong(&done, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) { @@ -1352,19 +1354,21 @@ class ChannelData::ClientChannelControlHelper } void UpdateState( - grpc_connectivity_state state, + grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override { grpc_error* disconnect_error = chand_->disconnect_error(); if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { const char* extra = disconnect_error == GRPC_ERROR_NONE ? "" : " (ignoring -- channel shutting down)"; - gpr_log(GPR_INFO, "chand=%p: update: state=%s picker=%p%s", chand_, - ConnectivityStateName(state), picker.get(), extra); + gpr_log(GPR_INFO, "chand=%p: update: state=%s status=(%s) picker=%p%s", + chand_, ConnectivityStateName(state), status.ToString().c_str(), + picker.get(), extra); } // Do update only if not shutting down. if (disconnect_error == GRPC_ERROR_NONE) { - chand_->UpdateStateAndPickerLocked(state, "helper", std::move(picker)); + chand_->UpdateStateAndPickerLocked(state, status, "helper", + std::move(picker)); } } @@ -1701,7 +1705,8 @@ ChannelData::~ChannelData() { } void ChannelData::UpdateStateAndPickerLocked( - grpc_connectivity_state state, const char* reason, + grpc_connectivity_state state, const absl::Status& status, + const char* reason, std::unique_ptr picker) { // Clean the control plane when entering IDLE. if (picker_ == nullptr) { @@ -1711,7 +1716,7 @@ void ChannelData::UpdateStateAndPickerLocked( received_first_resolver_result_ = false; } // Update connectivity state. - state_tracker_.SetState(state, reason); + state_tracker_.SetState(state, status, reason); if (channelz_node_ != nullptr) { channelz_node_->SetConnectivityState(state); channelz_node_->AddTraceEvent( @@ -1938,8 +1943,8 @@ void ChannelData::StartTransportOpLocked(grpc_transport_op* op) { static_cast(value) == GRPC_CHANNEL_IDLE) { if (disconnect_error() == GRPC_ERROR_NONE) { // Enter IDLE state. - UpdateStateAndPickerLocked(GRPC_CHANNEL_IDLE, "channel entering IDLE", - nullptr); + UpdateStateAndPickerLocked(GRPC_CHANNEL_IDLE, absl::Status(), + "channel entering IDLE", nullptr); } GRPC_ERROR_UNREF(op->disconnect_with_error); } else { @@ -1948,7 +1953,7 @@ void ChannelData::StartTransportOpLocked(grpc_transport_op* op) { GRPC_ERROR_NONE); disconnect_error_.Store(op->disconnect_with_error, MemoryOrder::RELEASE); UpdateStateAndPickerLocked( - GRPC_CHANNEL_SHUTDOWN, "shutdown from API", + GRPC_CHANNEL_SHUTDOWN, absl::Status(), "shutdown from API", absl::make_unique( GRPC_ERROR_REF(op->disconnect_with_error))); } diff --git a/src/core/ext/filters/client_channel/health/health_check_client.cc b/src/core/ext/filters/client_channel/health/health_check_client.cc index e708a59c571..5d65293af29 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.cc +++ b/src/core/ext/filters/client_channel/health/health_check_client.cc @@ -91,7 +91,11 @@ void HealthCheckClient::SetHealthStatusLocked(grpc_connectivity_state state, gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%s reason=%s", this, ConnectivityStateName(state), reason); } - if (watcher_ != nullptr) watcher_->Notify(state); + if (watcher_ != nullptr) + watcher_->Notify(state, + state == GRPC_CHANNEL_TRANSIENT_FAILURE + ? absl::Status(absl::StatusCode::kUnavailable, reason) + : absl::Status()); } void HealthCheckClient::Orphan() { diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 6a290a3f51b..81f5bb33b20 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -24,6 +24,7 @@ #include #include +#include "absl/status/status.h" #include "absl/strings/string_view.h" #include "src/core/ext/filters/client_channel/server_address.h" @@ -283,6 +284,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Sets the connectivity state and returns a new picker to be used /// by the client channel. virtual void UpdateState(grpc_connectivity_state state, + const absl::Status& status, std::unique_ptr) = 0; /// Requests that the resolver re-resolve. diff --git a/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc b/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc index 8d8003d185a..1464c718602 100644 --- a/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +++ b/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc @@ -45,7 +45,7 @@ class ChildPolicyHandler::Helper return parent_->channel_control_helper()->CreateSubchannel(args); } - void UpdateState(grpc_connectivity_state state, + void UpdateState(grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override { if (parent_->shutting_down_) return; // If this request is from the pending child policy, ignore it until @@ -55,8 +55,9 @@ class ChildPolicyHandler::Helper if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) { gpr_log(GPR_INFO, "[child_policy_handler %p] helper %p: pending child policy %p " - "reports state=%s", - parent_.get(), this, child_, ConnectivityStateName(state)); + "reports state=%s (%s)", + parent_.get(), this, child_, ConnectivityStateName(state), + status.ToString().c_str()); } if (state == GRPC_CHANNEL_CONNECTING) return; grpc_pollset_set_del_pollset_set( @@ -67,7 +68,8 @@ class ChildPolicyHandler::Helper // This request is from an outdated child, so ignore it. return; } - parent_->channel_control_helper()->UpdateState(state, std::move(picker)); + parent_->channel_control_helper()->UpdateState(state, status, + std::move(picker)); } void RequestReresolution() override { diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index e4248a6f556..878951866ee 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -304,7 +304,7 @@ class GrpcLb : public LoadBalancingPolicy { RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; - void UpdateState(grpc_connectivity_state state, + void UpdateState(grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override; void RequestReresolution() override; void AddTraceEvent(TraceSeverity severity, @@ -323,15 +323,16 @@ class GrpcLb : public LoadBalancingPolicy { ~StateWatcher() { parent_.reset(DEBUG_LOCATION, "StateWatcher"); } private: - void OnConnectivityStateChange(grpc_connectivity_state new_state) override { + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& status) override { if (parent_->fallback_at_startup_checks_pending_ && new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { // In TRANSIENT_FAILURE. Cancel the fallback timer and go into // fallback mode immediately. gpr_log(GPR_INFO, - "[grpclb %p] balancer channel in state TRANSIENT_FAILURE; " + "[grpclb %p] balancer channel in state:TRANSIENT_FAILURE (%s); " "entering fallback mode", - parent_.get()); + parent_.get(), status.ToString().c_str()); parent_->fallback_at_startup_checks_pending_ = false; grpc_timer_cancel(&parent_->lb_fallback_timer_); parent_->fallback_mode_ = true; @@ -660,6 +661,7 @@ RefCountedPtr GrpcLb::Helper::CreateSubchannel( } void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, + const absl::Status& status, std::unique_ptr picker) { if (parent_->shutting_down_) return; // Record whether child policy reports READY. @@ -690,16 +692,22 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, state != GRPC_CHANNEL_READY)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { gpr_log(GPR_INFO, - "[grpclb %p helper %p] state=%s passing child picker %p as-is", - parent_.get(), this, ConnectivityStateName(state), picker.get()); + "[grpclb %p helper %p] state=%s (%s) passing " + "child picker %p as-is", + parent_.get(), this, ConnectivityStateName(state), + status.ToString().c_str(), picker.get()); } - parent_->channel_control_helper()->UpdateState(state, std::move(picker)); + parent_->channel_control_helper()->UpdateState(state, status, + std::move(picker)); return; } // Cases 2 and 3a: wrap picker from the child in our own picker. if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { - gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping child picker %p", - parent_.get(), this, ConnectivityStateName(state), picker.get()); + gpr_log(GPR_INFO, + "[grpclb %p helper %p] state=%s (%s) wrapping child " + "picker %p", + parent_.get(), this, ConnectivityStateName(state), + status.ToString().c_str(), picker.get()); } RefCountedPtr client_stats; if (parent_->lb_calld_ != nullptr && @@ -707,7 +715,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, client_stats = parent_->lb_calld_->client_stats()->Ref(); } parent_->channel_control_helper()->UpdateState( - state, + state, status, absl::make_unique(parent_.get(), parent_->serverlist_, std::move(picker), std::move(client_stats))); } diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 246b15a3549..4a1f006cf64 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -30,6 +30,7 @@ #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/error_utils.h" namespace grpc_core { @@ -200,7 +201,7 @@ void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() { grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); return; } @@ -318,12 +319,13 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( "selected subchannel failed; switching to pending update"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); } else { p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, absl::make_unique(p->Ref( - DEBUG_LOCATION, "QueuePicker"))); + GRPC_CHANNEL_CONNECTING, absl::Status(), + absl::make_unique( + p->Ref(DEBUG_LOCATION, "QueuePicker"))); } } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { @@ -338,20 +340,22 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->selected_ = nullptr; p->subchannel_list_.reset(); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, absl::make_unique( - p->Ref(DEBUG_LOCATION, "QueuePicker"))); + GRPC_CHANNEL_IDLE, absl::Status(), + absl::make_unique( + p->Ref(DEBUG_LOCATION, "QueuePicker"))); } else { // This is unlikely but can happen when a subchannel has been asked // to reconnect by a different channel and this channel has dropped // some connectivity state notifications. if (connectivity_state == GRPC_CHANNEL_READY) { p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, + GRPC_CHANNEL_READY, absl::Status(), absl::make_unique(subchannel()->Ref())); } else { // CONNECTING p->channel_control_helper()->UpdateState( - connectivity_state, absl::make_unique( - p->Ref(DEBUG_LOCATION, "QueuePicker"))); + connectivity_state, absl::Status(), + absl::make_unique( + p->Ref(DEBUG_LOCATION, "QueuePicker"))); } } } @@ -394,7 +398,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( "failed to connect to all addresses"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); } } @@ -406,8 +410,9 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // Only update connectivity state in case 1. if (subchannel_list() == p->subchannel_list_.get()) { p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, absl::make_unique(p->Ref( - DEBUG_LOCATION, "QueuePicker"))); + GRPC_CHANNEL_CONNECTING, absl::Status(), + absl::make_unique( + p->Ref(DEBUG_LOCATION, "QueuePicker"))); } break; } @@ -446,7 +451,8 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { } p->selected_ = this; p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, absl::make_unique(subchannel()->Ref())); + GRPC_CHANNEL_READY, absl::Status(), + absl::make_unique(subchannel()->Ref())); for (size_t i = 0; i < subchannel_list()->num_subchannels(); ++i) { if (i != Index()) { subchannel_list()->subchannel(i)->ShutdownLocked(); diff --git a/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc b/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc index 19fc45f4f87..6b0489ceb16 100644 --- a/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +++ b/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc @@ -20,6 +20,7 @@ #include #include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" #include @@ -33,6 +34,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/work_serializer.h" +#include "src/core/lib/transport/error_utils.h" namespace grpc_core { @@ -113,6 +115,11 @@ class PriorityLb : public LoadBalancingPolicy { grpc_connectivity_state connectivity_state() const { return connectivity_state_; } + + const absl::Status& connectivity_status() const { + return connectivity_status_; + } + bool failover_timer_callback_pending() const { return failover_timer_callback_pending_; } @@ -150,6 +157,7 @@ class PriorityLb : public LoadBalancingPolicy { RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, + const absl::Status& status, std::unique_ptr picker) override; void RequestReresolution() override; void AddTraceEvent(TraceSeverity severity, @@ -164,7 +172,7 @@ class PriorityLb : public LoadBalancingPolicy { const grpc_channel_args* args); void OnConnectivityStateUpdateLocked( - grpc_connectivity_state state, + grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker); void StartFailoverTimerLocked(); @@ -180,6 +188,7 @@ class PriorityLb : public LoadBalancingPolicy { OrphanablePtr child_policy_; grpc_connectivity_state connectivity_state_ = GRPC_CHANNEL_CONNECTING; + absl::Status connectivity_status_; RefCountedPtr picker_wrapper_; // States for delayed removal. @@ -334,6 +343,7 @@ void PriorityLb::HandleChildConnectivityStateChangeLocked( // If it's still READY or IDLE, we stick with this child, so pass // the new picker up to our parent. channel_control_helper()->UpdateState(child->connectivity_state(), + child->connectivity_status(), child->GetPicker()); } else { // If it's no longer READY or IDLE, we should stop using it. @@ -380,6 +390,7 @@ void PriorityLb::HandleChildConnectivityStateChangeLocked( // The current priority has returned a new picker, so pass it up to // our parent. channel_control_helper()->UpdateState(child->connectivity_state(), + child->connectivity_status(), child->GetPicker()); } @@ -409,7 +420,7 @@ void PriorityLb::TryNextPriorityLocked(bool report_connecting) { if (child == nullptr) { if (report_connecting) { channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, + GRPC_CHANNEL_CONNECTING, absl::Status(), absl::make_unique(Ref(DEBUG_LOCATION, "QueuePicker"))); } child = MakeOrphanable( @@ -436,7 +447,7 @@ void PriorityLb::TryNextPriorityLocked(bool report_connecting) { } if (report_connecting) { channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, + GRPC_CHANNEL_CONNECTING, absl::Status(), absl::make_unique(Ref(DEBUG_LOCATION, "QueuePicker"))); } return; @@ -456,7 +467,7 @@ void PriorityLb::TryNextPriorityLocked(bool report_connecting) { GRPC_ERROR_CREATE_FROM_STATIC_STRING("no ready priority"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); } @@ -476,6 +487,7 @@ void PriorityLb::SelectPriorityLocked(uint32_t priority) { // Update picker. auto& child = children_[config_->priorities()[priority]]; channel_control_helper()->UpdateState(child->connectivity_state(), + child->connectivity_status(), child->GetPicker()); } @@ -584,15 +596,18 @@ void PriorityLb::ChildPriority::ResetBackoffLocked() { } void PriorityLb::ChildPriority::OnConnectivityStateUpdateLocked( - grpc_connectivity_state state, std::unique_ptr picker) { + grpc_connectivity_state state, const absl::Status& status, + std::unique_ptr picker) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) { gpr_log(GPR_INFO, - "[priority_lb %p] child %s (%p): state update: %s, picker %p", + "[priority_lb %p] child %s (%p): state update: %s (%s) picker %p", priority_policy_.get(), name_.c_str(), this, - ConnectivityStateName(state), picker.get()); + ConnectivityStateName(state), status.ToString().c_str(), + picker.get()); } // Store the state and picker. connectivity_state_ = state; + connectivity_status_ = status; picker_wrapper_ = MakeRefCounted(std::move(picker)); // If READY or TRANSIENT_FAILURE, cancel failover timer. if (state == GRPC_CHANNEL_READY || state == GRPC_CHANNEL_TRANSIENT_FAILURE) { @@ -646,7 +661,10 @@ void PriorityLb::ChildPriority::OnFailoverTimerLocked(grpc_error* error) { priority_policy_.get(), name_.c_str(), this); } failover_timer_callback_pending_ = false; - OnConnectivityStateUpdateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, nullptr); + OnConnectivityStateUpdateLocked( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::Status(absl::StatusCode::kUnavailable, "failover timer fired"), + nullptr); } Unref(DEBUG_LOCATION, "ChildPriority+OnFailoverTimerLocked"); GRPC_ERROR_UNREF(error); @@ -725,10 +743,11 @@ PriorityLb::ChildPriority::Helper::CreateSubchannel( } void PriorityLb::ChildPriority::Helper::UpdateState( - grpc_connectivity_state state, std::unique_ptr picker) { + grpc_connectivity_state state, const absl::Status& status, + std::unique_ptr picker) { if (priority_->priority_policy_->shutting_down_) return; // Notify the priority. - priority_->OnConnectivityStateUpdateLocked(state, std::move(picker)); + priority_->OnConnectivityStateUpdateLocked(state, status, std::move(picker)); } void PriorityLb::ChildPriority::Helper::AddTraceEvent( diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 56b71b69dfc..d1ad2ca35e7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -40,6 +40,7 @@ #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/static_metadata.h" namespace grpc_core { @@ -322,11 +323,11 @@ void RoundRobin::RoundRobinSubchannelList:: if (num_ready_ > 0) { /* 1) READY */ p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, absl::make_unique(p, this)); + GRPC_CHANNEL_READY, absl::Status(), absl::make_unique(p, this)); } else if (num_connecting_ > 0) { /* 2) CONNECTING */ p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, + GRPC_CHANNEL_CONNECTING, absl::Status(), absl::make_unique(p->Ref(DEBUG_LOCATION, "QueuePicker"))); } else if (num_transient_failure_ == num_subchannels()) { /* 3) TRANSIENT_FAILURE */ @@ -335,7 +336,7 @@ void RoundRobin::RoundRobinSubchannelList:: "connections to all backends failing"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); } } @@ -452,7 +453,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); subchannel_list_ = std::move(latest_pending_subchannel_list_); } else if (subchannel_list_ == nullptr) { diff --git a/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc b/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc index 96491b68642..83bc6cc9a54 100644 --- a/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +++ b/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc @@ -36,6 +36,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/work_serializer.h" +#include "src/core/lib/transport/error_utils.h" namespace grpc_core { @@ -146,6 +147,7 @@ class WeightedTargetLb : public LoadBalancingPolicy { RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, + const absl::Status& status, std::unique_ptr picker) override; void RequestReresolution() override; void AddTraceEvent(TraceSeverity severity, @@ -160,7 +162,7 @@ class WeightedTargetLb : public LoadBalancingPolicy { const grpc_channel_args* args); void OnConnectivityStateUpdateLocked( - grpc_connectivity_state state, + grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker); static void OnDelayedRemovalTimer(void* arg, grpc_error* error); @@ -375,6 +377,7 @@ void WeightedTargetLb::UpdateStateLocked() { this, ConnectivityStateName(connectivity_state)); } std::unique_ptr picker; + absl::Status status; switch (connectivity_state) { case GRPC_CHANNEL_READY: picker = absl::make_unique(std::move(picker_list)); @@ -385,11 +388,15 @@ void WeightedTargetLb::UpdateStateLocked() { absl::make_unique(Ref(DEBUG_LOCATION, "QueuePicker")); break; default: - picker = absl::make_unique( + grpc_error* error = grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "weighted_target: all children report state TRANSIENT_FAILURE")); + "weighted_target: all children report state TRANSIENT_FAILURE"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + status = grpc_error_to_absl_status(error); + picker = absl::make_unique(error); } - channel_control_helper()->UpdateState(connectivity_state, std::move(picker)); + channel_control_helper()->UpdateState(connectivity_state, status, + std::move(picker)); } // @@ -508,15 +515,17 @@ void WeightedTargetLb::WeightedChild::ResetBackoffLocked() { } void WeightedTargetLb::WeightedChild::OnConnectivityStateUpdateLocked( - grpc_connectivity_state state, std::unique_ptr picker) { + grpc_connectivity_state state, const absl::Status& status, + std::unique_ptr picker) { // Cache the picker in the WeightedChild. picker_wrapper_ = MakeRefCounted(std::move(picker)); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_weighted_target_trace)) { gpr_log(GPR_INFO, "[weighted_target_lb %p] WeightedChild %p %s: connectivity " - "state update: state=%s picker_wrapper=%p", + "state update: state=%s (%s) picker_wrapper=%p", weighted_target_policy_.get(), this, name_.c_str(), - ConnectivityStateName(state), picker_wrapper_.get()); + ConnectivityStateName(state), status.ToString().c_str(), + picker_wrapper_.get()); } // If the child reports IDLE, immediately tell it to exit idle. if (state == GRPC_CHANNEL_IDLE) child_policy_->ExitIdleLocked(); @@ -589,9 +598,11 @@ WeightedTargetLb::WeightedChild::Helper::CreateSubchannel( } void WeightedTargetLb::WeightedChild::Helper::UpdateState( - grpc_connectivity_state state, std::unique_ptr picker) { + grpc_connectivity_state state, const absl::Status& status, + std::unique_ptr picker) { if (weighted_child_->weighted_target_policy_->shutting_down_) return; - weighted_child_->OnConnectivityStateUpdateLocked(state, std::move(picker)); + weighted_child_->OnConnectivityStateUpdateLocked(state, status, + std::move(picker)); } void WeightedTargetLb::WeightedChild::Helper::RequestReresolution() { diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc index 500f1ac056b..fb161fcb26c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/transport/error_utils.h" namespace grpc_core { @@ -79,7 +80,7 @@ class CdsLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; - void UpdateState(grpc_connectivity_state state, + void UpdateState(grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override; void RequestReresolution() override; void AddTraceEvent(TraceSeverity severity, @@ -209,7 +210,7 @@ void CdsLb::ClusterWatcher::OnError(grpc_error* error) { // we keep running with the data we had previously. if (parent_->child_policy_ == nullptr) { parent_->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); } else { GRPC_ERROR_UNREF(error); @@ -221,13 +222,15 @@ void CdsLb::ClusterWatcher::OnResourceDoesNotExist() { "[cdslb %p] CDS resource for %s does not exist -- reporting " "TRANSIENT_FAILURE", parent_.get(), parent_->config_->cluster().c_str()); + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("CDS resource \"", parent_->config_->cluster(), + "\" does not exist") + .c_str()), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); parent_->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, - absl::make_unique( - GRPC_ERROR_CREATE_FROM_COPIED_STRING( - absl::StrCat("CDS resource \"", parent_->config_->cluster(), - "\" does not exist") - .c_str()))); + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), + absl::make_unique(error)); parent_->MaybeDestroyChildPolicyLocked(); } @@ -242,13 +245,16 @@ RefCountedPtr CdsLb::Helper::CreateSubchannel( } void CdsLb::Helper::UpdateState(grpc_connectivity_state state, + const absl::Status& status, std::unique_ptr picker) { if (parent_->shutting_down_ || parent_->child_policy_ == nullptr) return; if (GRPC_TRACE_FLAG_ENABLED(grpc_cds_lb_trace)) { - gpr_log(GPR_INFO, "[cdslb %p] state updated by child: %s", this, - ConnectivityStateName(state)); + gpr_log(GPR_INFO, + "[cdslb %p] state updated by child: %s message_state: (%s)", this, + ConnectivityStateName(state), status.ToString().c_str()); } - parent_->channel_control_helper()->UpdateState(state, std::move(picker)); + parent_->channel_control_helper()->UpdateState(state, status, + std::move(picker)); } void CdsLb::Helper::RequestReresolution() { diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc index c1bbf742cee..da9d0aaff7d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc @@ -40,6 +40,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/work_serializer.h" +#include "src/core/lib/transport/error_utils.h" #include "src/core/lib/uri/uri_parser.h" #define GRPC_EDS_DEFAULT_FALLBACK_TIMEOUT 10000 @@ -133,7 +134,7 @@ class EdsLb : public LoadBalancingPolicy { RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; - void UpdateState(grpc_connectivity_state state, + void UpdateState(grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override; // This is a no-op, because we get the addresses from the xds // client, which is a watch-based API. @@ -214,6 +215,7 @@ class EdsLb : public LoadBalancingPolicy { // The latest state and picker returned from the child policy. grpc_connectivity_state child_state_; + absl::Status child_status_; RefCountedPtr child_picker_; }; @@ -265,16 +267,21 @@ RefCountedPtr EdsLb::Helper::CreateSubchannel( } void EdsLb::Helper::UpdateState(grpc_connectivity_state state, + const absl::Status& status, std::unique_ptr picker) { if (eds_policy_->shutting_down_ || eds_policy_->child_policy_ == nullptr) { return; } if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) { - gpr_log(GPR_INFO, "[edslb %p] child policy updated state=%s picker=%p", - eds_policy_.get(), ConnectivityStateName(state), picker.get()); + gpr_log(GPR_INFO, + "[edslb %p] child policy updated state=%s (%s) " + "picker=%p", + eds_policy_.get(), ConnectivityStateName(state), + status.ToString().c_str(), picker.get()); } // Save the state and picker. eds_policy_->child_state_ = state; + eds_policy_->child_status_ = status; eds_policy_->child_picker_ = MakeRefCounted(std::move(picker)); // Wrap the picker in a DropPicker and pass it up. @@ -339,7 +346,7 @@ class EdsLb::EndpointWatcher : public XdsClient::EndpointWatcherInterface { // we keep running with the data we had previously. if (eds_policy_->child_policy_ == nullptr) { eds_policy_->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); } else { GRPC_ERROR_UNREF(error); @@ -351,11 +358,12 @@ class EdsLb::EndpointWatcher : public XdsClient::EndpointWatcherInterface { GPR_ERROR, "[edslb %p] EDS resource does not exist -- reporting TRANSIENT_FAILURE", eds_policy_.get()); + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("EDS resource does not exist"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); eds_policy_->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, - absl::make_unique( - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "EDS resource does not exist"))); + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), + absl::make_unique(error)); eds_policy_->MaybeDestroyChildPolicyLocked(); } @@ -688,7 +696,7 @@ EdsLb::CreateChildPolicyConfigLocked() { error), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error), absl::make_unique(error)); return nullptr; } @@ -769,13 +777,13 @@ void EdsLb::MaybeUpdateDropPickerLocked() { // If we're dropping all calls, report READY, regardless of what (or // whether) the child has reported. if (drop_config_ != nullptr && drop_config_->drop_all()) { - channel_control_helper()->UpdateState(GRPC_CHANNEL_READY, + channel_control_helper()->UpdateState(GRPC_CHANNEL_READY, absl::Status(), absl::make_unique(this)); return; } // Update only if we have a child picker. if (child_picker_ != nullptr) { - channel_control_helper()->UpdateState(child_state_, + channel_control_helper()->UpdateState(child_state_, child_status_, absl::make_unique(this)); } } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc b/src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc index 0aca12dfed2..51027574b32 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc @@ -120,7 +120,7 @@ class LrsLb : public LoadBalancingPolicy { RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; - void UpdateState(grpc_connectivity_state state, + void UpdateState(grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override; void RequestReresolution() override; void AddTraceEvent(TraceSeverity severity, @@ -157,6 +157,7 @@ class LrsLb : public LoadBalancingPolicy { // Latest state and picker reported by the child policy. grpc_connectivity_state state_ = GRPC_CHANNEL_IDLE; + absl::Status status_; RefCountedPtr picker_; }; @@ -266,10 +267,14 @@ void LrsLb::MaybeUpdatePickerLocked() { auto lrs_picker = absl::make_unique(picker_, locality_stats_); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_lrs_trace)) { - gpr_log(GPR_INFO, "[lrs_lb %p] updating connectivity: state=%s picker=%p", - this, ConnectivityStateName(state_), lrs_picker.get()); + gpr_log( + GPR_INFO, + "[lrs_lb %p] updating connectivity: state=%s status=(%s) picker=%p", + this, ConnectivityStateName(state_), status_.ToString().c_str(), + lrs_picker.get()); } - channel_control_helper()->UpdateState(state_, std::move(lrs_picker)); + channel_control_helper()->UpdateState(state_, status_, + std::move(lrs_picker)); } } @@ -325,15 +330,19 @@ RefCountedPtr LrsLb::Helper::CreateSubchannel( } void LrsLb::Helper::UpdateState(grpc_connectivity_state state, + const absl::Status& status, std::unique_ptr picker) { if (lrs_policy_->shutting_down_) return; if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_lrs_trace)) { - gpr_log(GPR_INFO, - "[lrs_lb %p] child connectivity state update: state=%s picker=%p", - lrs_policy_.get(), ConnectivityStateName(state), picker.get()); + gpr_log( + GPR_INFO, + "[lrs_lb %p] child connectivity state update: state=%s (%s) picker=%p", + lrs_policy_.get(), ConnectivityStateName(state), + status.ToString().c_str(), picker.get()); } // Save the state and picker. lrs_policy_->state_ = state; + lrs_policy_->status_ = status; lrs_policy_->picker_ = MakeRefCounted(std::move(picker)); // Wrap the picker and return it to the channel. lrs_policy_->MaybeUpdatePickerLocked(); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc index 2adc7cd9551..a3672e14bce 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc @@ -42,6 +42,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/work_serializer.h" +#include "src/core/lib/transport/error_utils.h" #define GRPC_XDS_ROUTING_CHILD_RETENTION_INTERVAL_MS (15 * 60 * 1000) @@ -165,6 +166,7 @@ class XdsRoutingLb : public LoadBalancingPolicy { RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, + const absl::Status& status, std::unique_ptr picker) override; void RequestReresolution() override; void AddTraceEvent(TraceSeverity severity, @@ -464,6 +466,7 @@ void XdsRoutingLb::UpdateStateLocked() { ConnectivityStateName(connectivity_state)); } std::unique_ptr picker; + absl::Status status; switch (connectivity_state) { case GRPC_CHANNEL_READY: { RoutePicker::RouteTable route_table; @@ -493,12 +496,15 @@ void XdsRoutingLb::UpdateStateLocked() { absl::make_unique(Ref(DEBUG_LOCATION, "QueuePicker")); break; default: - picker = absl::make_unique(grpc_error_set_int( + grpc_error* error = grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING( "TRANSIENT_FAILURE from XdsRoutingLb"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + status = grpc_error_to_absl_status(error); + picker = absl::make_unique(error); } - channel_control_helper()->UpdateState(connectivity_state, std::move(picker)); + channel_control_helper()->UpdateState(connectivity_state, status, + std::move(picker)); } // @@ -654,13 +660,15 @@ XdsRoutingLb::XdsRoutingChild::Helper::CreateSubchannel( } void XdsRoutingLb::XdsRoutingChild::Helper::UpdateState( - grpc_connectivity_state state, std::unique_ptr picker) { + grpc_connectivity_state state, const absl::Status& status, + std::unique_ptr picker) { if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_routing_lb_trace)) { gpr_log(GPR_INFO, - "[xds_routing_lb %p] child %s: received update: state=%s picker=%p", + "[xds_routing_lb %p] child %s: received update: state=%s (%s) " + "picker=%p", xds_routing_child_->xds_routing_policy_.get(), xds_routing_child_->name_.c_str(), ConnectivityStateName(state), - picker.get()); + status.ToString().c_str(), picker.get()); } if (xds_routing_child_->xds_routing_policy_->shutting_down_) return; // Cache the picker in the XdsRoutingChild. diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 356123c50ae..ce204f030e7 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -114,10 +114,11 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper return parent_->channel_control_helper()->CreateSubchannel(args); } - void UpdateState(grpc_connectivity_state state, + void UpdateState(grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override { if (parent_->resolver_ == nullptr) return; // Shutting down. - parent_->channel_control_helper()->UpdateState(state, std::move(picker)); + parent_->channel_control_helper()->UpdateState(state, status, + std::move(picker)); } void RequestReresolution() override { @@ -160,7 +161,7 @@ ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); } - channel_control_helper()->UpdateState(GRPC_CHANNEL_CONNECTING, + channel_control_helper()->UpdateState(GRPC_CHANNEL_CONNECTING, absl::Status(), absl::make_unique(Ref())); resolver_->StartLocked(); } @@ -214,7 +215,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { "Resolver transient failure", &error, 1); helper_->ResolverTransientFailure(GRPC_ERROR_REF(state_error)); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(state_error), absl::make_unique(state_error)); } GRPC_ERROR_UNREF(error); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 89a13a3ef74..26bc7f8549f 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -26,6 +26,8 @@ #include #include +#include "absl/strings/str_format.h" + #include #include @@ -325,7 +327,8 @@ class Subchannel::ConnectedSubchannelStateWatcher } private: - void OnConnectivityStateChange(grpc_connectivity_state new_state) override { + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& status) override { Subchannel* c = subchannel_; MutexLock lock(&c->mu_); switch (new_state) { @@ -343,7 +346,15 @@ class Subchannel::ConnectedSubchannelStateWatcher if (c->channelz_node() != nullptr) { c->channelz_node()->SetChildSocket(nullptr); } - c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE); + // We need to construct our own status if the underlying state was + // shutdown since the accompanying status will be StatusCode::OK + // otherwise. + c->SetConnectivityStateLocked( + GRPC_CHANNEL_TRANSIENT_FAILURE, + new_state == GRPC_CHANNEL_SHUTDOWN + ? absl::Status(absl::StatusCode::kUnavailable, + "Subchannel has disconnected.") + : status); c->backoff_begun_ = false; c->backoff_.Reset(); } @@ -354,7 +365,7 @@ class Subchannel::ConnectedSubchannelStateWatcher // a callback for READY, because that was the state we started // this watch from. And a connected subchannel should never go // from READY to CONNECTING or IDLE. - c->SetConnectivityStateLocked(new_state); + c->SetConnectivityStateLocked(new_state, status); } } } @@ -368,14 +379,15 @@ class Subchannel::AsyncWatcherNotifierLocked { public: AsyncWatcherNotifierLocked( RefCountedPtr watcher, - Subchannel* subchannel, grpc_connectivity_state state) + Subchannel* subchannel, grpc_connectivity_state state, + const absl::Status& status) : watcher_(std::move(watcher)) { RefCountedPtr connected_subchannel; if (state == GRPC_CHANNEL_READY) { connected_subchannel = subchannel->connected_subchannel_; } watcher_->PushConnectivityStateChange( - {state, std::move(connected_subchannel)}); + {state, status, std::move(connected_subchannel)}); ExecCtx::Run( DEBUG_LOCATION, GRPC_CLOSURE_INIT(&closure_, @@ -409,9 +421,10 @@ void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked( } void Subchannel::ConnectivityStateWatcherList::NotifyLocked( - Subchannel* subchannel, grpc_connectivity_state state) { + Subchannel* subchannel, grpc_connectivity_state state, + const absl::Status& status) { for (const auto& p : watchers_) { - new AsyncWatcherNotifierLocked(p.second, subchannel, state); + new AsyncWatcherNotifierLocked(p.second, subchannel, state, status); } } @@ -450,7 +463,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher grpc_connectivity_state initial_state, RefCountedPtr watcher) { if (state_ != initial_state) { - new AsyncWatcherNotifierLocked(watcher, subchannel_, state_); + new AsyncWatcherNotifierLocked(watcher, subchannel_, state_, status_); } watcher_list_.AddWatcherLocked(std::move(watcher)); } @@ -462,7 +475,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher bool HasWatchers() const { return !watcher_list_.empty(); } - void NotifyLocked(grpc_connectivity_state state) { + void NotifyLocked(grpc_connectivity_state state, const absl::Status& status) { if (state == GRPC_CHANNEL_READY) { // If we had not already notified for CONNECTING state, do so now. // (We may have missed this earlier, because if the transition @@ -470,13 +483,15 @@ class Subchannel::HealthWatcherMap::HealthWatcher // subchannel may not have sent us a notification for CONNECTING.) if (state_ != GRPC_CHANNEL_CONNECTING) { state_ = GRPC_CHANNEL_CONNECTING; - watcher_list_.NotifyLocked(subchannel_, state_); + status_ = status; + watcher_list_.NotifyLocked(subchannel_, state_, status); } // If we've become connected, start health checking. StartHealthCheckingLocked(); } else { state_ = state; - watcher_list_.NotifyLocked(subchannel_, state_); + status_ = status; + watcher_list_.NotifyLocked(subchannel_, state_, status); // We're not connected, so stop health checking. health_check_client_.reset(); } @@ -489,11 +504,13 @@ class Subchannel::HealthWatcherMap::HealthWatcher } private: - void OnConnectivityStateChange(grpc_connectivity_state new_state) override { + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& status) override { MutexLock lock(&subchannel_->mu_); if (new_state != GRPC_CHANNEL_SHUTDOWN && health_check_client_ != nullptr) { state_ = new_state; - watcher_list_.NotifyLocked(subchannel_, new_state); + status_ = status; + watcher_list_.NotifyLocked(subchannel_, new_state, status); } } @@ -508,6 +525,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher grpc_core::UniquePtr health_check_service_name_; OrphanablePtr health_check_client_; grpc_connectivity_state state_; + absl::Status status_; ConnectivityStateWatcherList watcher_list_; }; @@ -547,9 +565,10 @@ void Subchannel::HealthWatcherMap::RemoveWatcherLocked( if (!it->second->HasWatchers()) map_.erase(it); } -void Subchannel::HealthWatcherMap::NotifyLocked(grpc_connectivity_state state) { +void Subchannel::HealthWatcherMap::NotifyLocked(grpc_connectivity_state state, + const absl::Status& status) { for (const auto& p : map_) { - p.second->NotifyLocked(state); + p.second->NotifyLocked(state, status); } } @@ -826,7 +845,7 @@ void Subchannel::WatchConnectivityState( } if (health_check_service_name == nullptr) { if (state_ != initial_state) { - new AsyncWatcherNotifierLocked(watcher, this, state_); + new AsyncWatcherNotifierLocked(watcher, this, state_, status_); } watcher_list_.AddWatcherLocked(std::move(watcher)); } else { @@ -928,8 +947,10 @@ const char* SubchannelConnectivityStateChangeString( } // namespace // Note: Must be called with a state that is different from the current state. -void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) { +void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state, + const absl::Status& status) { state_ = state; + status_ = status; if (channelz_node_ != nullptr) { channelz_node_->UpdateConnectivityState(state); channelz_node_->AddTraceEvent( @@ -938,9 +959,9 @@ void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) { SubchannelConnectivityStateChangeString(state))); } // Notify non-health watchers. - watcher_list_.NotifyLocked(this, state); + watcher_list_.NotifyLocked(this, state, status); // Notify health watchers. - health_watcher_map_.NotifyLocked(state); + health_watcher_map_.NotifyLocked(state, status); } void Subchannel::MaybeStartConnectingLocked() { @@ -1012,7 +1033,7 @@ void Subchannel::ContinueConnectingLocked() { next_attempt_deadline_ = backoff_.NextAttemptTime(); args.deadline = std::max(next_attempt_deadline_, min_deadline); args.channel_args = args_; - SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING); + SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, absl::Status()); connector_->Connect(args, &connecting_result_, &on_connecting_finished_); } @@ -1031,7 +1052,8 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } else { gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error)); - c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE); + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, + grpc_error_to_absl_status(error)); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } } @@ -1091,7 +1113,7 @@ bool Subchannel::PublishTransportLocked() { connected_subchannel_->StartWatch( pollset_set_, MakeOrphanable(this)); // Report initial state. - SetConnectivityStateLocked(GRPC_CHANNEL_READY); + SetConnectivityStateLocked(GRPC_CHANNEL_READY, absl::Status()); return true; } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 9478fa7340c..e615c18c944 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -182,6 +182,7 @@ class Subchannel { public: struct ConnectivityStateChange { grpc_connectivity_state state; + absl::Status status; RefCountedPtr connected_subchannel; }; @@ -306,7 +307,8 @@ class Subchannel { void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher); // Notifies all watchers in the list about a change to state. - void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state); + void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state, + const absl::Status& status); void Clear() { watchers_.clear(); } @@ -339,7 +341,8 @@ class Subchannel { ConnectivityStateWatcherInterface* watcher); // Notifies the watcher when the subchannel's state changes. - void NotifyLocked(grpc_connectivity_state state); + void NotifyLocked(grpc_connectivity_state state, + const absl::Status& status); grpc_connectivity_state CheckConnectivityStateLocked( Subchannel* subchannel, const char* health_check_service_name); @@ -357,7 +360,8 @@ class Subchannel { class AsyncWatcherNotifierLocked; // Sets the subchannel's connectivity state to \a state. - void SetConnectivityStateLocked(grpc_connectivity_state state); + void SetConnectivityStateLocked(grpc_connectivity_state state, + const absl::Status& status); // Methods for connection. void MaybeStartConnectingLocked(); @@ -400,6 +404,7 @@ class Subchannel { // Connectivity state tracking. grpc_connectivity_state state_ = GRPC_CHANNEL_IDLE; + absl::Status status_; // The list of watchers without a health check service name. ConnectivityStateWatcherList watcher_list_; // The map of watchers with health check service names. diff --git a/src/core/ext/filters/client_channel/xds/xds_channel_secure.cc b/src/core/ext/filters/client_channel/xds/xds_channel_secure.cc index c218db86a17..9252e553cee 100644 --- a/src/core/ext/filters/client_channel/xds/xds_channel_secure.cc +++ b/src/core/ext/filters/client_channel/xds/xds_channel_secure.cc @@ -73,7 +73,7 @@ grpc_channel* CreateXdsChannel(const XdsBootstrap& bootstrap, if (!bootstrap.server().channel_creds.empty()) { for (size_t i = 0; i < bootstrap.server().channel_creds.size(); ++i) { if (bootstrap.server().channel_creds[i].type == "google_default") { - creds = grpc_google_default_credentials_create(); + creds = grpc_google_default_credentials_create(nullptr); break; } else if (bootstrap.server().channel_creds[i].type == "fake") { creds = grpc_fake_transport_security_credentials_create(); diff --git a/src/core/ext/filters/client_channel/xds/xds_client.cc b/src/core/ext/filters/client_channel/xds/xds_client.cc index 3010c6b23d0..88e335087e1 100644 --- a/src/core/ext/filters/client_channel/xds/xds_client.cc +++ b/src/core/ext/filters/client_channel/xds/xds_client.cc @@ -398,13 +398,15 @@ class XdsClient::ChannelState::StateWatcher parent_(std::move(parent)) {} private: - void OnConnectivityStateChange(grpc_connectivity_state new_state) override { + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& status) override { if (!parent_->shutting_down_ && new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { // In TRANSIENT_FAILURE. Notify all watchers of error. gpr_log(GPR_INFO, - "[xds_client %p] xds channel in state TRANSIENT_FAILURE", - parent_->xds_client()); + "[xds_client %p] xds channel in state:TRANSIENT_FAILURE " + "status_message:(%s)", + parent_->xds_client(), status.ToString().c_str()); parent_->xds_client()->NotifyOnError(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "xds channel in TRANSIENT_FAILURE")); } diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index 0cf6f542414..ef59d675770 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -229,7 +229,8 @@ class ConnectivityWatcher : public AsyncConnectivityStateWatcherInterface { } private: - void OnConnectivityStateChange(grpc_connectivity_state new_state) override { + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& /* status */) override { if (new_state != GRPC_CHANNEL_SHUTDOWN) return; { MutexLock lock(&chand_->max_age_timer_mu); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 8b7c7fe3db5..ddaed426bf6 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -18,6 +18,8 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "absl/strings/str_format.h" + #include #include #include @@ -29,7 +31,6 @@ #include #include -#include "absl/strings/str_format.h" #include "src/core/ext/transport/chttp2/transport/context_list.h" #include "src/core/ext/transport/chttp2/transport/frame_data.h" #include "src/core/ext/transport/chttp2/transport/internal.h" @@ -125,6 +126,7 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t); static void connectivity_state_set(grpc_chttp2_transport* t, grpc_connectivity_state state, + const absl::Status& status, const char* reason); static void benign_reclaimer(void* t, grpc_error* error); @@ -560,7 +562,8 @@ static void close_transport_locked(grpc_chttp2_transport* t, } GPR_ASSERT(error != GRPC_ERROR_NONE); t->closed_with_error = GRPC_ERROR_REF(error); - connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, "close_transport"); + connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, absl::Status(), + "close_transport"); if (t->ping_state.is_delayed_ping_timer_set) { grpc_timer_cancel(&t->ping_state.delayed_ping_timer); } @@ -1103,9 +1106,11 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, : static_cast(current_keepalive_time_ms * KEEPALIVE_TIME_BACKOFF_MULTIPLIER); } + absl::Status status = grpc_error_to_absl_status(t->goaway_error); // lie: use transient failure from the transport to indicate goaway has been - // received - connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, "got_goaway"); + // received. + connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, status, + "got_goaway"); } static void maybe_start_some_streams(grpc_chttp2_transport* t) { @@ -1140,6 +1145,8 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) { if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) { connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::Status(absl::StatusCode::kUnavailable, + "Transport Stream IDs exhausted"), "no_more_stream_ids"); } @@ -2915,10 +2922,11 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { static void connectivity_state_set(grpc_chttp2_transport* t, grpc_connectivity_state state, + const absl::Status& status, const char* reason) { GRPC_CHTTP2_IF_TRACING( gpr_log(GPR_INFO, "transport %p set connectivity_state=%d", t, state)); - t->state_tracker.SetState(state, reason); + t->state_tracker.SetState(state, status, reason); } // diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 49b9bf093ba..d40bffd6d09 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1132,7 +1132,8 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs, void close_transport_locked(inproc_transport* t) { INPROC_LOG(GPR_INFO, "close_transport %p %d", t, t->is_closed); - t->state_tracker.SetState(GRPC_CHANNEL_SHUTDOWN, "close transport"); + t->state_tracker.SetState(GRPC_CHANNEL_SHUTDOWN, absl::Status(), + "close transport"); if (!t->is_closed) { t->is_closed = true; /* Also end all streams on this transport */ diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index 4edbd86037f..9162bad47bc 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -49,6 +49,8 @@ using grpc_core::Json; /* -- Constants. -- */ #define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal." +#define GRPC_GOOGLE_CREDENTIAL_CREATION_ERROR \ + "Failed to create Google credentials" /* -- Default credentials. -- */ @@ -57,7 +59,6 @@ using grpc_core::Json; * means the detection is done via network test that is unreliable and the * unreliable result should not be referred by successive calls. */ static int g_metadata_server_available = 0; -static int g_is_on_gce = 0; static gpr_mu g_state_mu; /* Protect a metadata_server_detector instance that can be modified by more than * one gRPC threads */ @@ -89,7 +90,7 @@ grpc_google_default_channel_credentials::create_security_connector( bool use_alts = is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer; /* Return failure if ALTS is selected but not running on GCE. */ - if (use_alts && !g_is_on_gce) { + if (use_alts && alts_creds_ == nullptr) { gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE."); return nullptr; } @@ -273,59 +274,78 @@ end: return error; } -grpc_channel_credentials* grpc_google_default_credentials_create() { - grpc_channel_credentials* result = nullptr; - grpc_core::RefCountedPtr call_creds; - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Failed to create Google credentials"); - grpc_error* err; - grpc_core::ExecCtx exec_ctx; +static void update_tenancy() { + gpr_once_init(&g_once, init_default_credentials); + grpc_core::MutexLock lock(&g_state_mu); - GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ()); + /* Try a platform-provided hint for GCE. */ + if (!g_metadata_server_available) { + g_metadata_server_available = g_gce_tenancy_checker(); + } + /* TODO: Add a platform-provided hint for GAE. */ - gpr_once_init(&g_once, init_default_credentials); + /* Do a network test for metadata server. */ + if (!g_metadata_server_available) { + g_metadata_server_available = is_metadata_server_reachable(); + } +} + +static bool metadata_server_available() { + grpc_core::MutexLock lock(&g_state_mu); + return static_cast(g_metadata_server_available); +} + +static grpc_core::RefCountedPtr make_default_call_creds( + grpc_error** error) { + grpc_core::RefCountedPtr call_creds; + grpc_error* err; /* First, try the environment variable. */ char* path_from_env = gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR); if (path_from_env != nullptr) { err = create_default_creds_from_path(path_from_env, &call_creds); gpr_free(path_from_env); - if (err == GRPC_ERROR_NONE) goto end; - error = grpc_error_add_child(error, err); + if (err == GRPC_ERROR_NONE) return call_creds; + *error = grpc_error_add_child(*error, err); } /* Then the well-known file. */ err = create_default_creds_from_path( grpc_get_well_known_google_credentials_file_path(), &call_creds); - if (err == GRPC_ERROR_NONE) goto end; - error = grpc_error_add_child(error, err); + if (err == GRPC_ERROR_NONE) return call_creds; + *error = grpc_error_add_child(*error, err); - gpr_mu_lock(&g_state_mu); + update_tenancy(); - /* Try a platform-provided hint for GCE. */ - if (!g_metadata_server_available) { - g_is_on_gce = g_gce_tenancy_checker(); - g_metadata_server_available = g_is_on_gce; - } - /* TODO: Add a platform-provided hint for GAE. */ - - /* Do a network test for metadata server. */ - if (!g_metadata_server_available) { - g_metadata_server_available = is_metadata_server_reachable(); - } - gpr_mu_unlock(&g_state_mu); - - if (g_metadata_server_available) { + if (metadata_server_available()) { call_creds = grpc_core::RefCountedPtr( grpc_google_compute_engine_credentials_create(nullptr)); if (call_creds == nullptr) { - error = grpc_error_add_child( - error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Failed to get credentials from network")); + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + GRPC_GOOGLE_CREDENTIAL_CREATION_ERROR); + *error = grpc_error_add_child( + *error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Failed to get credentials from network")); } } -end: + return call_creds; +} + +grpc_channel_credentials* grpc_google_default_credentials_create( + grpc_call_credentials* call_credentials) { + grpc_channel_credentials* result = nullptr; + grpc_core::RefCountedPtr call_creds(call_credentials); + grpc_error* error = nullptr; + grpc_core::ExecCtx exec_ctx; + + GRPC_API_TRACE("grpc_google_default_credentials_create(%p)", 1, + (call_credentials)); + + if (call_creds == nullptr) { + call_creds = make_default_call_creds(&error); + } + if (call_creds != nullptr) { /* Create google default credentials. */ grpc_channel_credentials* ssl_creds = @@ -338,10 +358,8 @@ end: grpc_alts_credentials_options_destroy(options); auto creds = grpc_core::MakeRefCounted( - alts_creds != nullptr ? alts_creds->Ref() : nullptr, - ssl_creds != nullptr ? ssl_creds->Ref() : nullptr); - if (ssl_creds) ssl_creds->Unref(); - if (alts_creds) alts_creds->Unref(); + grpc_core::RefCountedPtr(alts_creds), + grpc_core::RefCountedPtr(ssl_creds)); result = grpc_composite_channel_credentials_create( creds.get(), call_creds.get(), nullptr); GPR_ASSERT(result != nullptr); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index cab0cd56c40..9b7c2262137 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1271,7 +1271,8 @@ class ConnectivityWatcher : public AsyncConnectivityStateWatcherInterface { } private: - void OnConnectivityStateChange(grpc_connectivity_state new_state) override { + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& /* status */) override { // Don't do anything until we are being shut down. if (new_state != GRPC_CHANNEL_SHUTDOWN) return; // Shut down channel. diff --git a/src/core/lib/transport/connectivity_state.cc b/src/core/lib/transport/connectivity_state.cc index 2d34f52e635..c2008ab82b7 100644 --- a/src/core/lib/transport/connectivity_state.cc +++ b/src/core/lib/transport/connectivity_state.cc @@ -58,9 +58,9 @@ const char* ConnectivityStateName(grpc_connectivity_state state) { class AsyncConnectivityStateWatcherInterface::Notifier { public: Notifier(RefCountedPtr watcher, - grpc_connectivity_state state, + grpc_connectivity_state state, const absl::Status& status, const std::shared_ptr& work_serializer) - : watcher_(std::move(watcher)), state_(state) { + : watcher_(std::move(watcher)), state_(state), status_(status) { if (work_serializer != nullptr) { work_serializer->Run( [this]() { SendNotification(this, GRPC_ERROR_NONE); }, @@ -76,21 +76,24 @@ class AsyncConnectivityStateWatcherInterface::Notifier { static void SendNotification(void* arg, grpc_error* /*ignored*/) { Notifier* self = static_cast(arg); if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { - gpr_log(GPR_INFO, "watcher %p: delivering async notification for %s", - self->watcher_.get(), ConnectivityStateName(self->state_)); + gpr_log(GPR_INFO, "watcher %p: delivering async notification for %s (%s)", + self->watcher_.get(), ConnectivityStateName(self->state_), + self->status_.ToString().c_str()); } - self->watcher_->OnConnectivityStateChange(self->state_); + self->watcher_->OnConnectivityStateChange(self->state_, self->status_); delete self; } RefCountedPtr watcher_; const grpc_connectivity_state state_; + const absl::Status status_; grpc_closure closure_; }; void AsyncConnectivityStateWatcherInterface::Notify( - grpc_connectivity_state state) { - new Notifier(Ref(), state, work_serializer_); // Deletes itself when done. + grpc_connectivity_state state, const absl::Status& status) { + new Notifier(Ref(), state, status, + work_serializer_); // Deletes itself when done. } // @@ -107,7 +110,7 @@ ConnectivityStateTracker::~ConnectivityStateTracker() { name_, this, p.first, ConnectivityStateName(current_state), ConnectivityStateName(GRPC_CHANNEL_SHUTDOWN)); } - p.second->Notify(GRPC_CHANNEL_SHUTDOWN); + p.second->Notify(GRPC_CHANNEL_SHUTDOWN, absl::Status()); } } @@ -126,7 +129,7 @@ void ConnectivityStateTracker::AddWatcher( name_, this, watcher.get(), ConnectivityStateName(initial_state), ConnectivityStateName(current_state)); } - watcher->Notify(current_state); + watcher->Notify(current_state, status_); } // If we're in state SHUTDOWN, don't add the watcher, so that it will // be orphaned immediately. @@ -145,15 +148,17 @@ void ConnectivityStateTracker::RemoveWatcher( } void ConnectivityStateTracker::SetState(grpc_connectivity_state state, + const absl::Status& status, const char* reason) { grpc_connectivity_state current_state = state_.Load(MemoryOrder::RELAXED); if (state == current_state) return; if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { - gpr_log(GPR_INFO, "ConnectivityStateTracker %s[%p]: %s -> %s (%s)", name_, - this, ConnectivityStateName(current_state), - ConnectivityStateName(state), reason); + gpr_log(GPR_INFO, "ConnectivityStateTracker %s[%p]: %s -> %s (%s, %s)", + name_, this, ConnectivityStateName(current_state), + ConnectivityStateName(state), reason, status.ToString().c_str()); } state_.Store(state, MemoryOrder::RELAXED); + status_ = status; for (const auto& p : watchers_) { if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { gpr_log(GPR_INFO, @@ -161,7 +166,7 @@ void ConnectivityStateTracker::SetState(grpc_connectivity_state state, name_, this, p.first, ConnectivityStateName(current_state), ConnectivityStateName(state)); } - p.second->Notify(state); + p.second->Notify(state, status); } // If the new state is SHUTDOWN, orphan all of the watchers. This // avoids the need for the callers to explicitly cancel them. diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h index 5ab62bed40c..f8a945eb035 100644 --- a/src/core/lib/transport/connectivity_state.h +++ b/src/core/lib/transport/connectivity_state.h @@ -21,6 +21,8 @@ #include +#include "absl/status/status.h" + #include #include "src/core/lib/debug/trace.h" @@ -49,7 +51,8 @@ class ConnectivityStateWatcherInterface virtual ~ConnectivityStateWatcherInterface() = default; // Notifies the watcher that the state has changed to new_state. - virtual void Notify(grpc_connectivity_state new_state) = 0; + virtual void Notify(grpc_connectivity_state new_state, + const absl::Status& status) = 0; void Orphan() override { Unref(); } }; @@ -64,7 +67,8 @@ class AsyncConnectivityStateWatcherInterface // Schedules a closure on the ExecCtx to invoke // OnConnectivityStateChange() asynchronously. - void Notify(grpc_connectivity_state new_state) override final; + void Notify(grpc_connectivity_state new_state, + const absl::Status& status) override final; protected: class Notifier; @@ -76,7 +80,8 @@ class AsyncConnectivityStateWatcherInterface : work_serializer_(std::move(work_serializer)) {} // Invoked asynchronously when Notify() is called. - virtual void OnConnectivityStateChange(grpc_connectivity_state new_state) = 0; + virtual void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& status) = 0; private: std::shared_ptr work_serializer_; @@ -91,8 +96,9 @@ class AsyncConnectivityStateWatcherInterface class ConnectivityStateTracker { public: ConnectivityStateTracker(const char* name, - grpc_connectivity_state state = GRPC_CHANNEL_IDLE) - : name_(name), state_(state) {} + grpc_connectivity_state state = GRPC_CHANNEL_IDLE, + const absl::Status& status = absl::Status()) + : name_(name), state_(state), status_(status) {} ~ConnectivityStateTracker(); @@ -110,15 +116,21 @@ class ConnectivityStateTracker { // Sets connectivity state. // Not thread safe; access must be serialized with an external lock. - void SetState(grpc_connectivity_state state, const char* reason); + void SetState(grpc_connectivity_state state, const absl::Status& status, + const char* reason); // Gets the current state. // Thread safe; no need to use an external lock. grpc_connectivity_state state() const; + // Get the current status. + // Not thread safe; access must be serialized with an external lock. + absl::Status status() const { return status_; } + private: const char* name_; Atomic state_; + absl::Status status_; // TODO(roth): Once we can use C++-14 heterogeneous lookups, this can // be a set instead of a map. std::map(status), + absl::string_view(reinterpret_cast( + GRPC_SLICE_START_PTR(message)), + GRPC_SLICE_LENGTH(message))); +} + bool grpc_error_has_clear_grpc_status(grpc_error* error) { intptr_t unused; if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &unused)) { diff --git a/src/core/lib/transport/error_utils.h b/src/core/lib/transport/error_utils.h index 9a46267f38a..e9b1a8f1d2f 100644 --- a/src/core/lib/transport/error_utils.h +++ b/src/core/lib/transport/error_utils.h @@ -21,6 +21,8 @@ #include +#include "absl/status/status.h" + #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/transport/http2_errors.h" @@ -37,6 +39,10 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline, grpc_http2_error_code* http_status, const char** error_string); +/// Utility Function to convert a grpc_error * \a error to an absl::Status. +/// Does NOT consume a ref to grpc_error. +absl::Status grpc_error_to_absl_status(grpc_error* error); + /// A utility function to check whether there is a clear status code that /// doesn't need to be guessed in \a error. This means that \a error or some /// child has GRPC_ERROR_INT_GRPC_STATUS set, or that it is GRPC_ERROR_NONE or diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 32ac91d4bbb..108762e76ab 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -97,7 +97,8 @@ std::shared_ptr WrapCallCredentials( std::shared_ptr GoogleDefaultCredentials() { grpc::GrpcLibraryCodegen init; // To call grpc_init(). - return WrapChannelCredentials(grpc_google_default_credentials_create()); + return WrapChannelCredentials( + grpc_google_default_credentials_create(nullptr)); } // Builds SSL Credentials given SSL specific options diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c index a1611d13518..ae9e469547d 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -131,7 +131,7 @@ PHP_METHOD(ChannelCredentials, invalidateDefaultRootsPem) { * @return ChannelCredentials The new default channel credentials object */ PHP_METHOD(ChannelCredentials, createDefault) { - grpc_channel_credentials *creds = grpc_google_default_credentials_create(); + grpc_channel_credentials *creds = grpc_google_default_credentials_create(NULL); zval *creds_object = grpc_php_wrap_channel_credentials(creds, NULL, false TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 25f76b8a9d9..9d1f81348cb 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -1868,6 +1868,23 @@ def alts_server_credentials(): return ServerCredentials(_cygrpc.server_credentials_alts()) +def compute_engine_channel_credentials(call_credentials): + """Creates a compute engine channel credential. + + This credential can only be used in a GCP environment as it relies on + a handshaker service. For more info about ALTS, see + https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security + + This channel credential is expected to be used as part of a composite + credential in conjunction with a call credentials that authenticates the + VM's default service account. If used with any other sort of call + credential, the connection may suddenly and unexpectedly begin failing RPCs. + """ + return ChannelCredentials( + _cygrpc.channel_credentials_compute_engine( + call_credentials._credentials)) + + def channel_ready_future(channel): """Creates a Future that tracks when a Channel is ready. diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 0ff3706d134..c75579cc04f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -380,3 +380,22 @@ def server_credentials_alts(): # Options can be destroyed as deep copy was performed. grpc_alts_credentials_options_destroy(c_options) return credentials + + +cdef class ComputeEngineChannelCredentials(ChannelCredentials): + cdef grpc_channel_credentials* _c_creds + cdef grpc_call_credentials* _call_creds + + def __cinit__(self, CallCredentials call_creds): + self._c_creds = NULL + self._call_creds = call_creds.c() + if self._call_creds == NULL: + raise ValueError("Call credentials may not be NULL.") + + cdef grpc_channel_credentials *c(self) except *: + self._c_creds = grpc_google_default_credentials_create(self._call_creds) + return self._c_creds + + +def channel_credentials_compute_engine(call_creds): + return ComputeEngineChannelCredentials(call_creds) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 98a71f92699..a7131355a07 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -504,7 +504,7 @@ cdef extern from "grpc/grpc_security.h": void grpc_set_ssl_roots_override_callback( grpc_ssl_roots_override_callback cb) nogil - grpc_channel_credentials *grpc_google_default_credentials_create() nogil + grpc_channel_credentials *grpc_google_default_credentials_create(grpc_call_credentials* call_credentials) nogil grpc_channel_credentials *grpc_ssl_credentials_create( const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, verify_peer_options *verify_options, void *reserved) nogil diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 5b9dc43d30d..cb217c93534 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -476,6 +476,7 @@ CORE_SOURCE_FILES = [ 'src/core/tsi/transport_security_grpc.cc', 'third_party/abseil-cpp/absl/base/dynamic_annotations.cc', 'third_party/abseil-cpp/absl/base/internal/cycleclock.cc', + 'third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc', 'third_party/abseil-cpp/absl/base/internal/raw_logging.cc', 'third_party/abseil-cpp/absl/base/internal/spinlock.cc', 'third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc', @@ -484,9 +485,18 @@ CORE_SOURCE_FILES = [ 'third_party/abseil-cpp/absl/base/internal/throw_delegate.cc', 'third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc', 'third_party/abseil-cpp/absl/base/log_severity.cc', + 'third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc', + 'third_party/abseil-cpp/absl/debugging/internal/demangle.cc', + 'third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc', + 'third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc', + 'third_party/abseil-cpp/absl/debugging/stacktrace.cc', + 'third_party/abseil-cpp/absl/debugging/symbolize.cc', 'third_party/abseil-cpp/absl/numeric/int128.cc', + 'third_party/abseil-cpp/absl/status/status.cc', + 'third_party/abseil-cpp/absl/status/status_payload_printer.cc', 'third_party/abseil-cpp/absl/strings/ascii.cc', 'third_party/abseil-cpp/absl/strings/charconv.cc', + 'third_party/abseil-cpp/absl/strings/cord.cc', 'third_party/abseil-cpp/absl/strings/escaping.cc', 'third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc', 'third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc', diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index 4685852162b..f38b82b030a 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -13,7 +13,7 @@ py_library( ) py_library( - name = "client", + name = "client_lib", srcs = ["client.py"], imports = ["../../"], deps = [ @@ -25,6 +25,13 @@ py_library( ], ) +py_binary( + name = "client", + srcs = ["client.py"], + python_version = "PY3", + deps = [":client_lib"], +) + py_library( name = "methods", srcs = ["methods.py"], diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py index 04b82c0b401..4d35f7ca32a 100644 --- a/src/python/grpcio_tests/tests/interop/client.py +++ b/src/python/grpcio_tests/tests/interop/client.py @@ -51,6 +51,10 @@ def parse_interop_client_args(): default=False, type=resources.parse_bool, help='replace platform root CAs with ca.pem') + parser.add_argument('--custom_credentials_type', + choices=["compute_engine_channel_creds"], + default=None, + help='use google default credentials') parser.add_argument('--server_host_override', type=str, help='the server host to which to claim to connect') @@ -60,6 +64,14 @@ def parse_interop_client_args(): parser.add_argument('--default_service_account', type=str, help='email address of the default service account') + parser.add_argument( + "--grpc_test_use_grpclb_with_child_policy", + type=str, + help=( + "If non-empty, set a static service config on channels created by " + + "grpc::CreateTestChannel, that configures the grpclb LB policy " + + "with a child policy being the value of this flag (e.g. round_robin " + + "or pick_first).")) return parser.parse_args() @@ -89,8 +101,27 @@ def _create_call_credentials(args): def get_secure_channel_parameters(args): call_credentials = _create_call_credentials(args) - channel_opts = None - if args.use_tls: + channel_opts = () + if args.grpc_test_use_grpclb_with_child_policy: + channel_opts += (( + "grpc.service_config", + '{"loadBalancingConfig": [{"grpclb": {"childPolicy": [{"%s": {}}]}}]}' + % args.grpc_test_use_grpclb_with_child_policy),) + if args.custom_credentials_type is not None: + if args.custom_credentials_type == "compute_engine_channel_creds": + assert call_credentials is None + google_credentials, unused_project_id = google_auth.default( + scopes=[args.oauth_scope]) + call_creds = grpc.metadata_call_credentials( + google_auth.transport.grpc.AuthMetadataPlugin( + credentials=google_credentials, + request=google_auth.transport.requests.Request())) + channel_credentials = grpc.compute_engine_channel_credentials( + call_creds) + else: + raise ValueError("Unknown credentials type '{}'".format( + args.custom_credentials_type)) + elif args.use_tls: if args.use_test_ca: root_certificates = resources.test_root_certificates() else: @@ -102,7 +133,7 @@ def get_secure_channel_parameters(args): channel_credentials, call_credentials) if args.server_host_override: - channel_opts = (( + channel_opts += (( 'grpc.ssl_target_name_override', args.server_host_override, ),) @@ -115,7 +146,7 @@ def get_secure_channel_parameters(args): def _create_channel(args): target = '{}:{}'.format(args.server_host, args.server_port) - if args.use_tls or args.use_alts: + if args.use_tls or args.use_alts or args.custom_credentials_type is not None: channel_credentials, options = get_secure_channel_parameters(args) return grpc.secure_channel(target, channel_credentials, options) else: diff --git a/src/python/grpcio_tests/tests_aio/interop/BUILD.bazel b/src/python/grpcio_tests/tests_aio/interop/BUILD.bazel index f67ad35cca7..4b908ecd47f 100644 --- a/src/python/grpcio_tests/tests_aio/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests_aio/interop/BUILD.bazel @@ -70,7 +70,7 @@ py_binary( deps = [ ":methods", "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/interop:client", + "//src/python/grpcio_tests/tests/interop:client_lib", "//src/python/grpcio_tests/tests/interop:resources", ], ) diff --git a/src/python/grpcio_tests/tests_aio/interop/client.py b/src/python/grpcio_tests/tests_aio/interop/client.py index 7731f3bd6eb..a4c5e12ceda 100644 --- a/src/python/grpcio_tests/tests_aio/interop/client.py +++ b/src/python/grpcio_tests/tests_aio/interop/client.py @@ -30,7 +30,7 @@ _LOGGER.setLevel(logging.DEBUG) def _create_channel(args): target = f'{args.server_host}:{args.server_port}' - if args.use_tls or args.use_alts: + if args.use_tls or args.use_alts or args.custom_credentials_type is not None: channel_credentials, options = interop_client_lib.get_secure_channel_parameters( args) return aio.secure_channel(target, channel_credentials, options) diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 37b864d5be4..ef9ee0fe6a7 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -120,12 +120,12 @@ grpc_auth_context_set_peer_identity_property_name_type grpc_auth_context_set_pee grpc_ssl_session_cache_create_lru_type grpc_ssl_session_cache_create_lru_import; grpc_ssl_session_cache_destroy_type grpc_ssl_session_cache_destroy_import; grpc_ssl_session_cache_create_channel_arg_type grpc_ssl_session_cache_create_channel_arg_import; +grpc_call_credentials_release_type grpc_call_credentials_release_import; grpc_channel_credentials_release_type grpc_channel_credentials_release_import; grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import; grpc_set_ssl_roots_override_callback_type grpc_set_ssl_roots_override_callback_import; grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import; grpc_ssl_credentials_create_ex_type grpc_ssl_credentials_create_ex_import; -grpc_call_credentials_release_type grpc_call_credentials_release_import; grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import; grpc_composite_call_credentials_create_type grpc_composite_call_credentials_create_import; grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import; @@ -394,12 +394,12 @@ void grpc_rb_load_imports(HMODULE library) { grpc_ssl_session_cache_create_lru_import = (grpc_ssl_session_cache_create_lru_type) GetProcAddress(library, "grpc_ssl_session_cache_create_lru"); grpc_ssl_session_cache_destroy_import = (grpc_ssl_session_cache_destroy_type) GetProcAddress(library, "grpc_ssl_session_cache_destroy"); grpc_ssl_session_cache_create_channel_arg_import = (grpc_ssl_session_cache_create_channel_arg_type) GetProcAddress(library, "grpc_ssl_session_cache_create_channel_arg"); + grpc_call_credentials_release_import = (grpc_call_credentials_release_type) GetProcAddress(library, "grpc_call_credentials_release"); grpc_channel_credentials_release_import = (grpc_channel_credentials_release_type) GetProcAddress(library, "grpc_channel_credentials_release"); grpc_google_default_credentials_create_import = (grpc_google_default_credentials_create_type) GetProcAddress(library, "grpc_google_default_credentials_create"); grpc_set_ssl_roots_override_callback_import = (grpc_set_ssl_roots_override_callback_type) GetProcAddress(library, "grpc_set_ssl_roots_override_callback"); grpc_ssl_credentials_create_import = (grpc_ssl_credentials_create_type) GetProcAddress(library, "grpc_ssl_credentials_create"); grpc_ssl_credentials_create_ex_import = (grpc_ssl_credentials_create_ex_type) GetProcAddress(library, "grpc_ssl_credentials_create_ex"); - grpc_call_credentials_release_import = (grpc_call_credentials_release_type) GetProcAddress(library, "grpc_call_credentials_release"); grpc_composite_channel_credentials_create_import = (grpc_composite_channel_credentials_create_type) GetProcAddress(library, "grpc_composite_channel_credentials_create"); grpc_composite_call_credentials_create_import = (grpc_composite_call_credentials_create_type) GetProcAddress(library, "grpc_composite_call_credentials_create"); grpc_google_compute_engine_credentials_create_import = (grpc_google_compute_engine_credentials_create_type) GetProcAddress(library, "grpc_google_compute_engine_credentials_create"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 260d673a668..b9bad36dd2d 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -335,10 +335,13 @@ extern grpc_ssl_session_cache_destroy_type grpc_ssl_session_cache_destroy_import typedef grpc_arg(*grpc_ssl_session_cache_create_channel_arg_type)(grpc_ssl_session_cache* cache); extern grpc_ssl_session_cache_create_channel_arg_type grpc_ssl_session_cache_create_channel_arg_import; #define grpc_ssl_session_cache_create_channel_arg grpc_ssl_session_cache_create_channel_arg_import +typedef void(*grpc_call_credentials_release_type)(grpc_call_credentials* creds); +extern grpc_call_credentials_release_type grpc_call_credentials_release_import; +#define grpc_call_credentials_release grpc_call_credentials_release_import typedef void(*grpc_channel_credentials_release_type)(grpc_channel_credentials* creds); extern grpc_channel_credentials_release_type grpc_channel_credentials_release_import; #define grpc_channel_credentials_release grpc_channel_credentials_release_import -typedef grpc_channel_credentials*(*grpc_google_default_credentials_create_type)(void); +typedef grpc_channel_credentials*(*grpc_google_default_credentials_create_type)(grpc_call_credentials* call_credentials); extern grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import; #define grpc_google_default_credentials_create grpc_google_default_credentials_create_import typedef void(*grpc_set_ssl_roots_override_callback_type)(grpc_ssl_roots_override_callback cb); @@ -350,9 +353,6 @@ extern grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import; typedef grpc_channel_credentials*(*grpc_ssl_credentials_create_ex_type)(const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const grpc_ssl_verify_peer_options* verify_options, void* reserved); extern grpc_ssl_credentials_create_ex_type grpc_ssl_credentials_create_ex_import; #define grpc_ssl_credentials_create_ex grpc_ssl_credentials_create_ex_import -typedef void(*grpc_call_credentials_release_type)(grpc_call_credentials* creds); -extern grpc_call_credentials_release_type grpc_call_credentials_release_import; -#define grpc_call_credentials_release grpc_call_credentials_release_import typedef grpc_channel_credentials*(*grpc_composite_channel_credentials_create_type)(grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds, void* reserved); extern grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import; #define grpc_composite_channel_credentials_create grpc_composite_channel_credentials_create_import diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template index 79a6262beb5..fb0f2d2e5ad 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template @@ -41,4 +41,5 @@ # Cloning from a local path sets RepositoryUrl to a path and breaks Source Link. # Override RepositoryUrl to a URL to fix Source Link. The value doesn't matter. - dotnet build --configuration Debug Grpc.DotNet.sln -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git + dotnet build --configuration Debug --output ./output/InteropTestsWebsite testassets/InteropTestsWebsite/InteropTestsWebsite.csproj -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git + dotnet build --configuration Debug --output ./output/InteropTestsClient testassets/InteropTestsClient/InteropTestsClient.csproj -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index eb07947597c..22f6cdb7573 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -1347,16 +1347,24 @@ static void set_google_default_creds_env_var_with_file_contents( gpr_free(creds_file_name); } +static bool test_gce_tenancy_checker(void) { + g_test_gce_tenancy_checker_called = true; + return g_test_is_on_gce; +} + static void test_google_default_creds_auth_key(void) { grpc_core::ExecCtx exec_ctx; grpc_composite_channel_credentials* creds; char* json_key = test_json_key_str(); grpc_flush_cached_google_default_credentials(); + set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); + g_test_gce_tenancy_checker_called = false; + g_test_is_on_gce = true; set_google_default_creds_env_var_with_file_contents( "json_key_google_default_creds", json_key); gpr_free(json_key); creds = reinterpret_cast( - grpc_google_default_credentials_create()); + grpc_google_default_credentials_create(nullptr)); auto* default_creds = reinterpret_cast( creds->inner_creds()); @@ -1368,6 +1376,7 @@ static void test_google_default_creds_auth_key(void) { strcmp(jwt->key().client_id, "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") == 0); + GPR_ASSERT(g_test_gce_tenancy_checker_called == false); creds->Unref(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } @@ -1379,7 +1388,7 @@ static void test_google_default_creds_refresh_token(void) { set_google_default_creds_env_var_with_file_contents( "refresh_token_google_default_creds", test_refresh_token_str); creds = reinterpret_cast( - grpc_google_default_credentials_create()); + grpc_google_default_credentials_create(nullptr)); auto* default_creds = reinterpret_cast( creds->inner_creds()); @@ -1411,11 +1420,6 @@ static int default_creds_metadata_server_detection_httpcli_get_success_override( static std::string null_well_known_creds_path_getter(void) { return ""; } -static bool test_gce_tenancy_checker(void) { - g_test_gce_tenancy_checker_called = true; - return g_test_is_on_gce; -} - static void test_google_default_creds_gce(void) { grpc_core::ExecCtx exec_ctx; expected_md emd[] = { @@ -1435,7 +1439,7 @@ static void test_google_default_creds_gce(void) { /* Simulate a successful detection of GCE. */ grpc_composite_channel_credentials* creds = reinterpret_cast( - grpc_google_default_credentials_create()); + grpc_google_default_credentials_create(nullptr)); /* Verify that the default creds actually embeds a GCE creds. */ GPR_ASSERT(creds != nullptr); @@ -1474,7 +1478,7 @@ static void test_google_default_creds_non_gce(void) { httpcli_post_should_not_be_called); grpc_composite_channel_credentials* creds = reinterpret_cast( - grpc_google_default_credentials_create()); + grpc_google_default_credentials_create(nullptr)); /* Verify that the default creds actually embeds a GCE creds. */ GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds->call_creds() != nullptr); @@ -1512,16 +1516,105 @@ static void test_no_google_default_creds(void) { default_creds_gce_detection_httpcli_get_failure_override, httpcli_post_should_not_be_called); /* Simulate a successful detection of GCE. */ - GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); + GPR_ASSERT(grpc_google_default_credentials_create(nullptr) == nullptr); /* Try a second one. GCE detection should occur again. */ g_test_gce_tenancy_checker_called = false; - GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); + GPR_ASSERT(grpc_google_default_credentials_create(nullptr) == nullptr); GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ grpc_override_well_known_credentials_path_getter(nullptr); grpc_httpcli_set_override(nullptr, nullptr); } +static void test_google_default_creds_call_creds_specified(void) { + expected_md emd[] = { + {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; + request_metadata_state* state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + grpc_core::ExecCtx exec_ctx; + grpc_flush_cached_google_default_credentials(); + grpc_call_credentials* call_creds = + grpc_google_compute_engine_credentials_create(nullptr); + set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); + g_test_gce_tenancy_checker_called = false; + g_test_is_on_gce = true; + grpc_httpcli_set_override( + default_creds_metadata_server_detection_httpcli_get_success_override, + httpcli_post_should_not_be_called); + grpc_composite_channel_credentials* channel_creds = + reinterpret_cast( + grpc_google_default_credentials_create(call_creds)); + GPR_ASSERT(g_test_gce_tenancy_checker_called == false); + GPR_ASSERT(channel_creds != nullptr); + GPR_ASSERT(channel_creds->call_creds() != nullptr); + grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, + httpcli_post_should_not_be_called); + run_request_metadata_test(channel_creds->mutable_call_creds(), auth_md_ctx, + state); + grpc_core::ExecCtx::Get()->Flush(); + channel_creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); +} + +struct fake_call_creds : public grpc_call_credentials { + public: + explicit fake_call_creds() : grpc_call_credentials("fake") { + grpc_slice key = grpc_slice_from_static_string("foo"); + grpc_slice value = grpc_slice_from_static_string("oof"); + dummy_md_ = grpc_mdelem_from_slices(key, value); + grpc_slice_unref(key); + grpc_slice_unref(value); + } + + ~fake_call_creds() { GRPC_MDELEM_UNREF(dummy_md_); } + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_add(md_array, dummy_md_); + return true; + } + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) {} + + private: + grpc_mdelem dummy_md_; +}; + +static void test_google_default_creds_not_default(void) { + expected_md emd[] = {{"foo", "oof"}}; + request_metadata_state* state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + grpc_core::ExecCtx exec_ctx; + grpc_flush_cached_google_default_credentials(); + grpc_core::RefCountedPtr call_creds = + grpc_core::MakeRefCounted(); + set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); + g_test_gce_tenancy_checker_called = false; + g_test_is_on_gce = true; + grpc_httpcli_set_override( + default_creds_metadata_server_detection_httpcli_get_success_override, + httpcli_post_should_not_be_called); + grpc_composite_channel_credentials* channel_creds = + reinterpret_cast( + grpc_google_default_credentials_create(call_creds.release())); + GPR_ASSERT(g_test_gce_tenancy_checker_called == false); + GPR_ASSERT(channel_creds != nullptr); + GPR_ASSERT(channel_creds->call_creds() != nullptr); + run_request_metadata_test(channel_creds->mutable_call_creds(), auth_md_ctx, + state); + grpc_core::ExecCtx::Get()->Flush(); + channel_creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); +} + typedef enum { PLUGIN_INITIAL_STATE, PLUGIN_GET_METADATA_CALLED_STATE, @@ -1825,6 +1918,8 @@ int main(int argc, char** argv) { test_google_default_creds_gce(); test_google_default_creds_non_gce(); test_no_google_default_creds(); + test_google_default_creds_call_creds_specified(); + test_google_default_creds_not_default(); test_metadata_plugin_success(); test_metadata_plugin_failure(); test_get_well_known_google_credentials_file_path(); diff --git a/test/core/surface/lame_client_test.cc b/test/core/surface/lame_client_test.cc index 812b1455094..c63335445d7 100644 --- a/test/core/surface/lame_client_test.cc +++ b/test/core/surface/lame_client_test.cc @@ -30,7 +30,8 @@ class Watcher : public grpc_core::ConnectivityStateWatcherInterface { public: - void Notify(grpc_connectivity_state new_state) override { + void Notify(grpc_connectivity_state new_state, + const absl::Status& /* status */) override { GPR_ASSERT(new_state == GRPC_CHANNEL_SHUTDOWN); } }; diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 1b119317969..67edc35f6b0 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -164,12 +164,12 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_ssl_session_cache_create_lru); printf("%lx", (unsigned long) grpc_ssl_session_cache_destroy); printf("%lx", (unsigned long) grpc_ssl_session_cache_create_channel_arg); + printf("%lx", (unsigned long) grpc_call_credentials_release); printf("%lx", (unsigned long) grpc_channel_credentials_release); printf("%lx", (unsigned long) grpc_google_default_credentials_create); printf("%lx", (unsigned long) grpc_set_ssl_roots_override_callback); printf("%lx", (unsigned long) grpc_ssl_credentials_create); printf("%lx", (unsigned long) grpc_ssl_credentials_create_ex); - printf("%lx", (unsigned long) grpc_call_credentials_release); printf("%lx", (unsigned long) grpc_composite_channel_credentials_create); printf("%lx", (unsigned long) grpc_composite_call_credentials_create); printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create); diff --git a/test/core/transport/chttp2/too_many_pings_test.cc b/test/core/transport/chttp2/too_many_pings_test.cc index 708ddd1cfde..308b7216e12 100644 --- a/test/core/transport/chttp2/too_many_pings_test.cc +++ b/test/core/transport/chttp2/too_many_pings_test.cc @@ -65,7 +65,6 @@ grpc_status_code PerformCall(grpc_channel* channel, grpc_server* server, cq_verifier* cqv = cq_verifier_create(cq); grpc_op ops[6]; grpc_op* op; - grpc_metadata_array initial_metadata_recv; grpc_metadata_array trailing_metadata_recv; grpc_metadata_array request_metadata_recv; grpc_call_details call_details; @@ -78,7 +77,6 @@ grpc_status_code PerformCall(grpc_channel* channel, grpc_server* server, grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); GPR_ASSERT(c); - grpc_metadata_array_init(&initial_metadata_recv); grpc_metadata_array_init(&trailing_metadata_recv); grpc_metadata_array_init(&request_metadata_recv); grpc_call_details_init(&call_details); @@ -111,7 +109,6 @@ grpc_status_code PerformCall(grpc_channel* channel, grpc_server* server, cq_verify(cqv); // cleanup grpc_slice_unref(details); - grpc_metadata_array_destroy(&initial_metadata_recv); grpc_metadata_array_destroy(&trailing_metadata_recv); grpc_metadata_array_destroy(&request_metadata_recv); grpc_call_details_destroy(&call_details); diff --git a/test/core/transport/connectivity_state_test.cc b/test/core/transport/connectivity_state_test.cc index 23bd100e686..e0bd8d02198 100644 --- a/test/core/transport/connectivity_state_test.cc +++ b/test/core/transport/connectivity_state_test.cc @@ -42,116 +42,164 @@ TEST(ConnectivityStateName, Basic) { class Watcher : public ConnectivityStateWatcherInterface { public: - Watcher(int* count, grpc_connectivity_state* output, + Watcher(int* count, grpc_connectivity_state* output, absl::Status* status, bool* destroyed = nullptr) - : count_(count), output_(output), destroyed_(destroyed) {} + : count_(count), + output_(output), + status_(status), + destroyed_(destroyed) {} ~Watcher() { if (destroyed_ != nullptr) *destroyed_ = true; } - void Notify(grpc_connectivity_state new_state) override { + void Notify(grpc_connectivity_state new_state, + const absl::Status& status) override { ++*count_; *output_ = new_state; + *status_ = status; } private: int* count_; grpc_connectivity_state* output_; + absl::Status* status_; bool* destroyed_; }; TEST(StateTracker, SetAndGetState) { - ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING); + ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING, + absl::Status()); EXPECT_EQ(tracker.state(), GRPC_CHANNEL_CONNECTING); - tracker.SetState(GRPC_CHANNEL_READY, "whee"); + EXPECT_TRUE(tracker.status().ok()); + tracker.SetState(GRPC_CHANNEL_READY, absl::Status(), "whee"); EXPECT_EQ(tracker.state(), GRPC_CHANNEL_READY); + EXPECT_TRUE(tracker.status().ok()); + absl::Status transient_failure_status(absl::StatusCode::kUnavailable, + "status for testing"); + tracker.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, transient_failure_status, + "reason"); + EXPECT_EQ(tracker.state(), GRPC_CHANNEL_TRANSIENT_FAILURE); + EXPECT_EQ(tracker.status(), transient_failure_status); } TEST(StateTracker, NotificationUponAddingWatcher) { int count = 0; grpc_connectivity_state state = GRPC_CHANNEL_IDLE; + absl::Status status; ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING); tracker.AddWatcher(GRPC_CHANNEL_IDLE, - MakeOrphanable(&count, &state)); + MakeOrphanable(&count, &state, &status)); EXPECT_EQ(count, 1); EXPECT_EQ(state, GRPC_CHANNEL_CONNECTING); + EXPECT_TRUE(status.ok()); +} + +TEST(StateTracker, NotificationUponAddingWatcherWithTransientFailure) { + int count = 0; + grpc_connectivity_state state = GRPC_CHANNEL_IDLE; + absl::Status status; + absl::Status transient_failure_status(absl::StatusCode::kUnavailable, + "status for testing"); + ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_TRANSIENT_FAILURE, + transient_failure_status); + tracker.AddWatcher(GRPC_CHANNEL_IDLE, + MakeOrphanable(&count, &state, &status)); + EXPECT_EQ(count, 1); + EXPECT_EQ(state, GRPC_CHANNEL_TRANSIENT_FAILURE); + EXPECT_EQ(status, transient_failure_status); } TEST(StateTracker, NotificationUponStateChange) { int count = 0; grpc_connectivity_state state = GRPC_CHANNEL_IDLE; + absl::Status status; ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE); tracker.AddWatcher(GRPC_CHANNEL_IDLE, - MakeOrphanable(&count, &state)); + MakeOrphanable(&count, &state, &status)); EXPECT_EQ(count, 0); EXPECT_EQ(state, GRPC_CHANNEL_IDLE); - tracker.SetState(GRPC_CHANNEL_CONNECTING, "whee"); + EXPECT_TRUE(status.ok()); + absl::Status transient_failure_status(absl::StatusCode::kUnavailable, + "status for testing"); + tracker.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, transient_failure_status, + "whee"); EXPECT_EQ(count, 1); - EXPECT_EQ(state, GRPC_CHANNEL_CONNECTING); + EXPECT_EQ(state, GRPC_CHANNEL_TRANSIENT_FAILURE); + EXPECT_EQ(status, transient_failure_status); } TEST(StateTracker, SubscribeThenUnsubscribe) { int count = 0; grpc_connectivity_state state = GRPC_CHANNEL_IDLE; + absl::Status status; bool destroyed = false; ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE); ConnectivityStateWatcherInterface* watcher = - new Watcher(&count, &state, &destroyed); + new Watcher(&count, &state, &status, &destroyed); tracker.AddWatcher(GRPC_CHANNEL_IDLE, OrphanablePtr(watcher)); // No initial notification, since we started the watch from the // current state. EXPECT_EQ(count, 0); EXPECT_EQ(state, GRPC_CHANNEL_IDLE); + EXPECT_TRUE(status.ok()); // Cancel watch. This should not generate another notification. tracker.RemoveWatcher(watcher); EXPECT_TRUE(destroyed); EXPECT_EQ(count, 0); EXPECT_EQ(state, GRPC_CHANNEL_IDLE); + EXPECT_TRUE(status.ok()); } TEST(StateTracker, OrphanUponShutdown) { int count = 0; grpc_connectivity_state state = GRPC_CHANNEL_IDLE; + absl::Status status; bool destroyed = false; ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE); ConnectivityStateWatcherInterface* watcher = - new Watcher(&count, &state, &destroyed); + new Watcher(&count, &state, &status, &destroyed); tracker.AddWatcher(GRPC_CHANNEL_IDLE, OrphanablePtr(watcher)); // No initial notification, since we started the watch from the // current state. EXPECT_EQ(count, 0); EXPECT_EQ(state, GRPC_CHANNEL_IDLE); + EXPECT_TRUE(status.ok()); // Set state to SHUTDOWN. - tracker.SetState(GRPC_CHANNEL_SHUTDOWN, "shutting down"); + tracker.SetState(GRPC_CHANNEL_SHUTDOWN, absl::Status(), "shutting down"); EXPECT_TRUE(destroyed); EXPECT_EQ(count, 1); EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN); + EXPECT_TRUE(status.ok()); } TEST(StateTracker, AddWhenAlreadyShutdown) { int count = 0; grpc_connectivity_state state = GRPC_CHANNEL_IDLE; + absl::Status status; bool destroyed = false; - ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN); + ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN, + absl::Status()); ConnectivityStateWatcherInterface* watcher = - new Watcher(&count, &state, &destroyed); + new Watcher(&count, &state, &status, &destroyed); tracker.AddWatcher(GRPC_CHANNEL_IDLE, OrphanablePtr(watcher)); EXPECT_TRUE(destroyed); EXPECT_EQ(count, 1); EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN); + EXPECT_TRUE(status.ok()); } TEST(StateTracker, NotifyShutdownAtDestruction) { int count = 0; grpc_connectivity_state state = GRPC_CHANNEL_IDLE; + absl::Status status; { ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE); tracker.AddWatcher(GRPC_CHANNEL_IDLE, - MakeOrphanable(&count, &state)); + MakeOrphanable(&count, &state, &status)); // No initial notification, since we started the watch from the // current state. EXPECT_EQ(count, 0); @@ -165,10 +213,11 @@ TEST(StateTracker, NotifyShutdownAtDestruction) { TEST(StateTracker, DoNotNotifyShutdownAtDestructionIfAlreadyInShutdown) { int count = 0; grpc_connectivity_state state = GRPC_CHANNEL_SHUTDOWN; + absl::Status status; { ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN); tracker.AddWatcher(GRPC_CHANNEL_SHUTDOWN, - MakeOrphanable(&count, &state)); + MakeOrphanable(&count, &state, &status)); // No initial notification, since we started the watch from the // current state. EXPECT_EQ(count, 0); diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 56978b97949..5aa5dabafa0 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -142,10 +142,10 @@ class TestPickArgsLb : public ForwardingLoadBalancingPolicy { return parent_->channel_control_helper()->CreateSubchannel(args); } - void UpdateState(grpc_connectivity_state state, + void UpdateState(grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override { parent_->channel_control_helper()->UpdateState( - state, absl::make_unique(std::move(picker), cb_)); + state, status, absl::make_unique(std::move(picker), cb_)); } void RequestReresolution() override { @@ -252,10 +252,10 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy return parent_->channel_control_helper()->CreateSubchannel(args); } - void UpdateState(grpc_connectivity_state state, + void UpdateState(grpc_connectivity_state state, const absl::Status& status, std::unique_ptr picker) override { parent_->channel_control_helper()->UpdateState( - state, absl::make_unique(std::move(picker), cb_)); + state, status, absl::make_unique(std::move(picker), cb_)); } void RequestReresolution() override { diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh index 31f21ce7839..20a61c07eae 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -39,4 +39,5 @@ fi # Cloning from a local path sets RepositoryUrl to a path and breaks Source Link. # Override RepositoryUrl to a URL to fix Source Link. The value doesn't matter. -dotnet build --configuration Debug Grpc.DotNet.sln -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git +dotnet build --configuration Debug --output ./output/InteropTestsWebsite testassets/InteropTestsWebsite/InteropTestsWebsite.csproj -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git +dotnet build --configuration Debug --output ./output/InteropTestsClient testassets/InteropTestsClient/InteropTestsClient.csproj -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index eff5288b205..32e247553b0 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -190,8 +190,8 @@ class CSharpCoreCLRLanguage: class AspNetCoreLanguage: def __init__(self): - self.client_cwd = '../grpc-dotnet/testassets/InteropTestsClient/bin/Debug/netcoreapp3.0' - self.server_cwd = '../grpc-dotnet/testassets/InteropTestsWebsite/bin/Debug/netcoreapp3.0' + self.client_cwd = '../grpc-dotnet/output/InteropTestsClient' + self.server_cwd = '../grpc-dotnet/output/InteropTestsWebsite' self.safename = str(self) def cloud_to_prod_env(self):