Line data Source code
1 : #include "source/extensions/formatter/metadata/metadata.h" 2 : 3 : #include <string> 4 : 5 : #include "source/common/config/metadata.h" 6 : #include "source/common/formatter/substitution_formatter.h" 7 : #include "source/common/http/utility.h" 8 : #include "source/common/protobuf/utility.h" 9 : #include "source/common/runtime/runtime_features.h" 10 : 11 : namespace Envoy { 12 : namespace Extensions { 13 : namespace Formatter { 14 : 15 : // Metadata formatter for route's metadata. 16 : class RouteMetadataFormatter : public ::Envoy::Formatter::MetadataFormatter { 17 : public: 18 : RouteMetadataFormatter(const std::string& filter_namespace, const std::vector<std::string>& path, 19 : absl::optional<size_t> max_length) 20 : : ::Envoy::Formatter::MetadataFormatter(filter_namespace, path, max_length, 21 : [](const StreamInfo::StreamInfo& stream_info) 22 0 : -> const envoy::config::core::v3::Metadata* { 23 0 : auto route = stream_info.route(); 24 : 25 0 : if (route == nullptr) { 26 0 : return nullptr; 27 0 : } 28 0 : return &route->metadata(); 29 0 : }) {} 30 : }; 31 : 32 : // Metadata formatter for listener metadata. 33 : class ListenerMetadataFormatter : public ::Envoy::Formatter::MetadataFormatter { 34 : public: 35 : ListenerMetadataFormatter(const std::string& filter_namespace, 36 : const std::vector<std::string>& path, absl::optional<size_t> max_length) 37 : : ::Envoy::Formatter::MetadataFormatter( 38 : filter_namespace, path, max_length, 39 : [](const StreamInfo::StreamInfo& stream_info) 40 0 : -> const envoy::config::core::v3::Metadata* { 41 0 : const auto listener_info = stream_info.downstreamAddressProvider().listenerInfo(); 42 0 : if (listener_info) { 43 0 : return &listener_info->metadata(); 44 0 : } 45 0 : return nullptr; 46 0 : }) {} 47 : }; 48 : 49 : // Constructor registers all types of supported metadata along with the 50 : // handlers accessing the required metadata type. 51 0 : MetadataFormatterCommandParser::MetadataFormatterCommandParser() { 52 0 : metadata_formatter_providers_["DYNAMIC"] = [](const std::string& filter_namespace, 53 0 : const std::vector<std::string>& path, 54 0 : absl::optional<size_t> max_length) { 55 0 : return std::make_unique<::Envoy::Formatter::DynamicMetadataFormatter>(filter_namespace, path, 56 0 : max_length); 57 0 : }; 58 0 : metadata_formatter_providers_["CLUSTER"] = [](const std::string& filter_namespace, 59 0 : const std::vector<std::string>& path, 60 0 : absl::optional<size_t> max_length) { 61 0 : return std::make_unique<::Envoy::Formatter::ClusterMetadataFormatter>(filter_namespace, path, 62 0 : max_length); 63 0 : }; 64 0 : metadata_formatter_providers_["ROUTE"] = [](const std::string& filter_namespace, 65 0 : const std::vector<std::string>& path, 66 0 : absl::optional<size_t> max_length) { 67 0 : return std::make_unique<RouteMetadataFormatter>(filter_namespace, path, max_length); 68 0 : }; 69 0 : metadata_formatter_providers_["UPSTREAM_HOST"] = [](const std::string& filter_namespace, 70 0 : const std::vector<std::string>& path, 71 0 : absl::optional<size_t> max_length) { 72 0 : return std::make_unique<::Envoy::Formatter::UpstreamHostMetadataFormatter>(filter_namespace, 73 0 : path, max_length); 74 0 : }; 75 : 76 0 : metadata_formatter_providers_["LISTENER"] = [](const std::string& filter_namespace, 77 0 : const std::vector<std::string>& path, 78 0 : absl::optional<size_t> max_length) { 79 0 : return std::make_unique<ListenerMetadataFormatter>(filter_namespace, path, max_length); 80 0 : }; 81 0 : } 82 : 83 : ::Envoy::Formatter::FormatterProviderPtr 84 : MetadataFormatterCommandParser::parse(const std::string& command, const std::string& subcommand, 85 0 : absl::optional<size_t>& max_length) const { 86 0 : if (command == "METADATA") { 87 : // Extract type of metadata and keys. 88 0 : std::string type, filter_namespace; 89 0 : std::vector<std::string> path; 90 : 91 0 : ::Envoy::Formatter::SubstitutionFormatUtils::parseSubcommand(subcommand, ':', type, 92 0 : filter_namespace, path); 93 : 94 0 : auto provider = metadata_formatter_providers_.find(type); 95 0 : if (provider == metadata_formatter_providers_.end()) { 96 0 : throw EnvoyException(absl::StrCat(type, " is not supported type of metadata")); 97 0 : } 98 : 99 : // Return a pointer to formatter provider. 100 0 : return std::make_unique<Envoy::Formatter::StreamInfoFormatter>( 101 0 : provider->second(filter_namespace, path, max_length)); 102 0 : } 103 0 : return nullptr; 104 0 : } 105 : 106 : } // namespace Formatter 107 : } // namespace Extensions 108 : } // namespace Envoy