1 // 2 // Copyright 2024 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef GRPC_SRC_CORE_XDS_GRPC_XDS_METADATA_H 18 #define GRPC_SRC_CORE_XDS_GRPC_XDS_METADATA_H 19 20 #include <memory> 21 #include <string> 22 #include <utility> 23 24 #include "absl/container/flat_hash_map.h" 25 #include "absl/strings/str_cat.h" 26 #include "absl/strings/string_view.h" 27 #include "src/core/util/down_cast.h" 28 #include "src/core/util/json/json.h" 29 #include "src/core/util/json/json_writer.h" 30 #include "src/core/util/validation_errors.h" 31 32 namespace grpc_core { 33 34 // Interface for metadata value types. 35 class XdsMetadataValue { 36 public: 37 virtual ~XdsMetadataValue() = default; 38 39 // The proto message name. 40 virtual absl::string_view type() const = 0; 41 42 bool operator==(const XdsMetadataValue& other) const { 43 return type() == other.type() && Equals(other); 44 } 45 bool operator!=(const XdsMetadataValue& other) const { 46 return !(*this == other); 47 } 48 49 virtual std::string ToString() const = 0; 50 51 private: 52 // Called only if the type() methods return the same thing. 53 virtual bool Equals(const XdsMetadataValue& other) const = 0; 54 }; 55 56 // Metadata map. 57 class XdsMetadataMap { 58 public: 59 void Insert(absl::string_view key, std::unique_ptr<XdsMetadataValue> value); 60 61 const XdsMetadataValue* Find(absl::string_view key) const; 62 63 template <typename T> FindType(absl::string_view key)64 const T* FindType(absl::string_view key) const { 65 auto it = map_.find(key); 66 if (it == map_.end()) return nullptr; 67 if (it->second->type() != T::Type()) return nullptr; 68 return DownCast<const T*>(it->second.get()); 69 } 70 empty()71 bool empty() const { return map_.empty(); } size()72 size_t size() const { return map_.size(); } 73 74 bool operator==(const XdsMetadataMap& other) const; 75 76 std::string ToString() const; 77 78 private: 79 absl::flat_hash_map<std::string, std::unique_ptr<XdsMetadataValue>> map_; 80 }; 81 82 // Concrete metadata value type for google.protobuf.Struct. 83 class XdsStructMetadataValue : public XdsMetadataValue { 84 public: XdsStructMetadataValue(Json json)85 explicit XdsStructMetadataValue(Json json) : json_(std::move(json)) {} 86 Type()87 static absl::string_view Type() { return "google.protobuf.Struct"; } 88 type()89 absl::string_view type() const override { return Type(); } 90 json()91 const Json& json() const { return json_; } 92 ToString()93 std::string ToString() const override { 94 return absl::StrCat(type(), "{", JsonDump(json_), "}"); 95 } 96 97 private: Equals(const XdsMetadataValue & other)98 bool Equals(const XdsMetadataValue& other) const override { 99 return json_ == DownCast<const XdsStructMetadataValue&>(other).json_; 100 } 101 102 Json json_; 103 }; 104 105 // Concrete metadata value type for GCP Authn filter Audience. 106 class XdsGcpAuthnAudienceMetadataValue : public XdsMetadataValue { 107 public: XdsGcpAuthnAudienceMetadataValue(absl::string_view url)108 explicit XdsGcpAuthnAudienceMetadataValue(absl::string_view url) 109 : url_(url) {} 110 Type()111 static absl::string_view Type() { 112 return "envoy.extensions.filters.http.gcp_authn.v3.Audience"; 113 } 114 type()115 absl::string_view type() const override { return Type(); } 116 url()117 const std::string& url() const { return url_; } 118 ToString()119 std::string ToString() const override { 120 return absl::StrCat(type(), "{url=\"", url_, "\"}"); 121 } 122 123 private: Equals(const XdsMetadataValue & other)124 bool Equals(const XdsMetadataValue& other) const override { 125 return url_ == 126 DownCast<const XdsGcpAuthnAudienceMetadataValue&>(other).url_; 127 } 128 129 std::string url_; 130 }; 131 132 // Concrete metadata value type for addresses. 133 class XdsAddressMetadataValue : public XdsMetadataValue { 134 public: XdsAddressMetadataValue(std::string address)135 explicit XdsAddressMetadataValue(std::string address) 136 : address_(std::move(address)) {} 137 Type()138 static absl::string_view Type() { return "envoy.config.core.v3.Address"; } 139 type()140 absl::string_view type() const override { return Type(); } 141 address()142 const std::string& address() const { return address_; } 143 ToString()144 std::string ToString() const override { 145 return absl::StrCat(type(), "{address=\"", address_, "\"}"); 146 } 147 148 private: Equals(const XdsMetadataValue & other)149 bool Equals(const XdsMetadataValue& other) const override { 150 return address_ == DownCast<const XdsAddressMetadataValue&>(other).address_; 151 } 152 153 std::string address_; 154 }; 155 156 } // namespace grpc_core 157 158 #endif // GRPC_SRC_CORE_XDS_GRPC_XDS_METADATA_H 159