1 // 2 // 3 // Copyright 2023 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef GRPC_SRC_CPP_EXT_CSM_METADATA_EXCHANGE_H 20 #define GRPC_SRC_CPP_EXT_CSM_METADATA_EXCHANGE_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include <memory> 25 #include <string> 26 #include <utility> 27 #include <vector> 28 29 #include "absl/strings/string_view.h" 30 #include "google/protobuf/struct.upb.h" 31 #include "opentelemetry/sdk/common/attribute_utils.h" 32 #include "upb/mem/arena.hpp" 33 34 #include "src/core/lib/slice/slice.h" 35 #include "src/core/lib/transport/metadata_batch.h" 36 #include "src/cpp/ext/otel/otel_plugin.h" 37 38 namespace grpc { 39 namespace internal { 40 41 class ServiceMeshLabelsInjector : public LabelsInjector { 42 public: 43 explicit ServiceMeshLabelsInjector( 44 const opentelemetry::sdk::common::AttributeMap& map); 45 // Read the incoming initial metadata to get the set of labels to be added to 46 // metrics. 47 std::unique_ptr<LabelsIterable> GetLabels( 48 grpc_metadata_batch* incoming_initial_metadata) const override; 49 50 // Modify the outgoing initial metadata with metadata information to be sent 51 // to the peer. 52 void AddLabels(grpc_metadata_batch* outgoing_initial_metadata, 53 LabelsIterable* labels_from_incoming_metadata) const override; 54 55 // Add optional labels to the traced calls. 56 bool AddOptionalLabels( 57 bool is_client, 58 absl::Span<const grpc_core::RefCountedStringValue> optional_labels, 59 opentelemetry::nostd::function_ref< 60 bool(opentelemetry::nostd::string_view, 61 opentelemetry::common::AttributeValue)> 62 callback) const override; 63 64 // Gets the size of the actual optional labels. GetOptionalLabelsSize(bool is_client,absl::Span<const grpc_core::RefCountedStringValue>)65 size_t GetOptionalLabelsSize( 66 bool is_client, 67 absl::Span<const grpc_core::RefCountedStringValue> /*optional_labels*/) 68 const override { 69 return is_client ? 2 : 0; 70 } 71 72 const std::vector<std::pair<absl::string_view, std::string>>& TestOnlyLocalLabels()73 TestOnlyLocalLabels() const { 74 return local_labels_; 75 } 76 TestOnlySerializedLabels()77 const grpc_core::Slice& TestOnlySerializedLabels() const { 78 return serialized_labels_to_send_; 79 } 80 81 private: 82 std::vector<std::pair<absl::string_view, std::string>> local_labels_; 83 grpc_core::Slice serialized_labels_to_send_; 84 }; 85 86 // A LabelsIterable class provided by ServiceMeshLabelsInjector. EXPOSED FOR 87 // TESTING PURPOSES ONLY. 88 class MeshLabelsIterable : public LabelsIterable { 89 public: 90 enum class GcpResourceType : std::uint8_t { kGke, kGce, kUnknown }; 91 92 MeshLabelsIterable( 93 const std::vector<std::pair<absl::string_view, std::string>>& 94 local_labels, 95 grpc_core::Slice remote_metadata); 96 97 absl::optional<std::pair<absl::string_view, absl::string_view>> Next() 98 override; 99 100 size_t Size() const override; 101 ResetIteratorPosition()102 void ResetIteratorPosition() override { pos_ = 0; } 103 104 // Returns true if the peer sent a non-empty base64 encoded 105 // "x-envoy-peer-metadata" metadata. GotRemoteLabels()106 bool GotRemoteLabels() const { return struct_pb_ != nullptr; } 107 108 private: 109 upb::Arena arena_; 110 google_protobuf_Struct* struct_pb_ = nullptr; 111 const std::vector<std::pair<absl::string_view, std::string>>& local_labels_; 112 GcpResourceType remote_type_ = GcpResourceType::kUnknown; 113 uint32_t pos_ = 0; 114 }; 115 116 // Returns the mesh ID by reading and parsing the bootstrap file. Returns 117 // "unknown" if for some reason, mesh ID could not be figured out. 118 // EXPOSED FOR TESTING PURPOSES ONLY. 119 std::string GetMeshId(); 120 121 } // namespace internal 122 } // namespace grpc 123 124 #endif // GRPC_SRC_CPP_EXT_CSM_METADATA_EXCHANGE_H 125