diff --git a/src/cpp/ext/csm/BUILD b/src/cpp/ext/csm/BUILD index f58c6d14c8b..411a3b3075a 100644 --- a/src/cpp/ext/csm/BUILD +++ b/src/cpp/ext/csm/BUILD @@ -52,9 +52,11 @@ grpc_cc_library( language = "c++", visibility = ["//:__subpackages__"], deps = [ + "//:gpr", "//:gpr_platform", "//:grpc_base", "//:protobuf_struct_upb", + "//:uri_parser", "//src/core:env", "//src/core:error", "//src/core:json", diff --git a/src/cpp/ext/csm/csm_observability.cc b/src/cpp/ext/csm/csm_observability.cc index 168030cac20..cff3d5d327c 100644 --- a/src/cpp/ext/csm/csm_observability.cc +++ b/src/cpp/ext/csm/csm_observability.cc @@ -20,8 +20,12 @@ #include "src/cpp/ext/csm/csm_observability.h" +#include #include +#include + +#include "src/core/lib/uri/uri_parser.h" #include "src/cpp/ext/otel/otel_plugin.h" namespace grpc { @@ -71,8 +75,27 @@ CsmObservabilityBuilder& CsmObservabilityBuilder::SetTargetAttributeFilter( absl::StatusOr CsmObservabilityBuilder::BuildAndRegister() { builder_.BuildAndRegisterGlobal(); + builder_.SetTargetSelector(CsmChannelTargetSelector); return CsmObservability(); } +bool CsmChannelTargetSelector(absl::string_view target) { + auto uri = grpc_core::URI::Parse(target); + if (!uri.ok()) { + gpr_log(GPR_ERROR, "Failed to parse URI: %s", std::string(target).c_str()); + return false; + } + // CSM channels should have an "xds" scheme + if (uri->scheme() != "xds") { + return false; + } + // If set, the authority should be TD + if (!uri->authority().empty() && + uri->authority() != "traffic-director-global.xds.googleapis.com") { + return false; + } + return true; +} + } // namespace internal } // namespace grpc diff --git a/src/cpp/ext/csm/csm_observability.h b/src/cpp/ext/csm/csm_observability.h index 683b3ea83ea..ca3e4af8094 100644 --- a/src/cpp/ext/csm/csm_observability.h +++ b/src/cpp/ext/csm/csm_observability.h @@ -76,6 +76,10 @@ class CsmObservabilityBuilder { OpenTelemetryPluginBuilder builder_; }; +// EXPOSED FOR TESTING PURPOSES ONLY +// Returns true if the channel is a CSM channel. +bool CsmChannelTargetSelector(absl::string_view target); + } // namespace internal } // namespace grpc diff --git a/test/cpp/ext/csm/csm_observability_test.cc b/test/cpp/ext/csm/csm_observability_test.cc index 84320b76d34..4ac0b006021 100644 --- a/test/cpp/ext/csm/csm_observability_test.cc +++ b/test/cpp/ext/csm/csm_observability_test.cc @@ -37,6 +37,29 @@ TEST(GsmDependencyTest, GoogleCloudOpenTelemetryDependency) { EXPECT_NE(google::cloud::otel::MakeResourceDetector(), nullptr); } +TEST(CsmChannelTargetSelectorTest, NonXdsTargets) { + EXPECT_FALSE(internal::CsmChannelTargetSelector("foo.bar.google.com")); + EXPECT_FALSE(internal::CsmChannelTargetSelector("dns:///foo.bar.google.com")); + EXPECT_FALSE( + internal::CsmChannelTargetSelector("dns:///foo.bar.google.com:1234")); + EXPECT_FALSE(internal::CsmChannelTargetSelector( + "dns://authority/foo.bar.google.com:1234")); +} + +TEST(CsmChannelTargetSelectorTest, XdsTargets) { + EXPECT_TRUE(internal::CsmChannelTargetSelector("xds:///foo")); + EXPECT_TRUE(internal::CsmChannelTargetSelector("xds:///foo.bar")); +} + +TEST(CsmChannelTargetSelectorTest, XdsTargetsWithNonTDAuthority) { + EXPECT_FALSE(internal::CsmChannelTargetSelector("xds://authority/foo")); +} + +TEST(CsmChannelTargetSelectorTest, XdsTargetsWithTDAuthority) { + EXPECT_TRUE(internal::CsmChannelTargetSelector( + "xds://traffic-director-global.xds.googleapis.com/foo")); +} + } // namespace } // namespace testing } // namespace grpc