• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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