// // // Copyright 2023 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // #ifndef GRPC_SRC_CPP_EXT_CSM_METADATA_EXCHANGE_H #define GRPC_SRC_CPP_EXT_CSM_METADATA_EXCHANGE_H #include #include #include #include #include #include "absl/strings/string_view.h" #include "google/protobuf/struct.upb.h" #include "opentelemetry/sdk/common/attribute_utils.h" #include "upb/mem/arena.hpp" #include "src/core/lib/slice/slice.h" #include "src/core/lib/transport/metadata_batch.h" #include "src/cpp/ext/otel/otel_plugin.h" namespace grpc { namespace internal { class ServiceMeshLabelsInjector : public LabelsInjector { public: explicit ServiceMeshLabelsInjector( const opentelemetry::sdk::common::AttributeMap& map); // Read the incoming initial metadata to get the set of labels to be added to // metrics. std::unique_ptr GetLabels( grpc_metadata_batch* incoming_initial_metadata) const override; // Modify the outgoing initial metadata with metadata information to be sent // to the peer. void AddLabels(grpc_metadata_batch* outgoing_initial_metadata, LabelsIterable* labels_from_incoming_metadata) const override; // Add optional labels to the traced calls. bool AddOptionalLabels( bool is_client, absl::Span optional_labels, opentelemetry::nostd::function_ref< bool(opentelemetry::nostd::string_view, opentelemetry::common::AttributeValue)> callback) const override; // Gets the size of the actual optional labels. size_t GetOptionalLabelsSize( bool is_client, absl::Span /*optional_labels*/) const override { return is_client ? 2 : 0; } const std::vector>& TestOnlyLocalLabels() const { return local_labels_; } const grpc_core::Slice& TestOnlySerializedLabels() const { return serialized_labels_to_send_; } private: std::vector> local_labels_; grpc_core::Slice serialized_labels_to_send_; }; // A LabelsIterable class provided by ServiceMeshLabelsInjector. EXPOSED FOR // TESTING PURPOSES ONLY. class MeshLabelsIterable : public LabelsIterable { public: enum class GcpResourceType : std::uint8_t { kGke, kGce, kUnknown }; MeshLabelsIterable( const std::vector>& local_labels, grpc_core::Slice remote_metadata); absl::optional> Next() override; size_t Size() const override; void ResetIteratorPosition() override { pos_ = 0; } // Returns true if the peer sent a non-empty base64 encoded // "x-envoy-peer-metadata" metadata. bool GotRemoteLabels() const { return struct_pb_ != nullptr; } private: upb::Arena arena_; google_protobuf_Struct* struct_pb_ = nullptr; const std::vector>& local_labels_; GcpResourceType remote_type_ = GcpResourceType::kUnknown; uint32_t pos_ = 0; }; // Returns the mesh ID by reading and parsing the bootstrap file. Returns // "unknown" if for some reason, mesh ID could not be figured out. // EXPOSED FOR TESTING PURPOSES ONLY. std::string GetMeshId(); } // namespace internal } // namespace grpc #endif // GRPC_SRC_CPP_EXT_CSM_METADATA_EXCHANGE_H