Lines
100 %
Functions
#include "source/extensions/formatter/metadata/metadata.h"
#include <string>
#include "source/common/config/metadata.h"
#include "source/common/formatter/stream_info_formatter.h"
#include "source/common/formatter/substitution_formatter.h"
#include "source/common/http/utility.h"
#include "source/common/protobuf/utility.h"
#include "source/common/runtime/runtime_features.h"
namespace Envoy {
namespace Extensions {
namespace Formatter {
// Metadata formatter for route's metadata.
class RouteMetadataFormatter : public ::Envoy::Formatter::MetadataFormatter {
public:
RouteMetadataFormatter(absl::string_view filter_namespace,
const std::vector<absl::string_view>& path,
absl::optional<size_t> max_length)
: ::Envoy::Formatter::MetadataFormatter(filter_namespace, path, max_length,
[](const StreamInfo::StreamInfo& stream_info)
-> const envoy::config::core::v3::Metadata* {
auto route = stream_info.route();
if (route == nullptr) {
return nullptr;
}
return &route->metadata();
}) {}
};
// Metadata formatter for listener metadata.
class ListenerMetadataFormatter : public ::Envoy::Formatter::MetadataFormatter {
ListenerMetadataFormatter(absl::string_view filter_namespace,
: ::Envoy::Formatter::MetadataFormatter(
filter_namespace, path, max_length,
const auto listener_info = stream_info.downstreamAddressProvider().listenerInfo();
if (listener_info) {
return &listener_info->metadata();
// Metadata formatter for listener filter chain metadata.
class ListenerFilterChainMetadataFormatter : public ::Envoy::Formatter::MetadataFormatter {
ListenerFilterChainMetadataFormatter(absl::string_view filter_namespace,
const auto filter_chain_info =
stream_info.downstreamAddressProvider().filterChainInfo();
if (filter_chain_info) {
return &filter_chain_info->metadata();
// Metadata formatter for virtual host metadata.
class VirtualHostMetadataFormatter : public ::Envoy::Formatter::MetadataFormatter {
VirtualHostMetadataFormatter(absl::string_view filter_namespace,
const auto& vhost = stream_info.virtualHost();
return vhost != nullptr ? &vhost->metadata()
: nullptr;
// Map used to dispatch types of metadata to individual handlers which will
// access required metadata object.
using FormatterProviderFunc = std::function<::Envoy::Formatter::StreamInfoFormatterProviderPtr(
absl::string_view filter_namespace, const std::vector<absl::string_view>& path,
absl::optional<size_t> max_length)>;
using FormatterProviderFuncTable = absl::flat_hash_map<std::string, FormatterProviderFunc>;
const auto& formatterProviderFuncTable() {
CONSTRUCT_ON_FIRST_USE(
FormatterProviderFuncTable,
{
{"DYNAMIC",
[](absl::string_view filter_namespace, const std::vector<absl::string_view>& path,
absl::optional<size_t> max_length) {
return std::make_unique<::Envoy::Formatter::DynamicMetadataFormatter>(
filter_namespace, path, max_length);
}},
{"CLUSTER",
return std::make_unique<::Envoy::Formatter::ClusterMetadataFormatter>(
{"ROUTE",
return std::make_unique<RouteMetadataFormatter>(filter_namespace, path, max_length);
{"UPSTREAM_HOST",
return std::make_unique<::Envoy::Formatter::UpstreamHostMetadataFormatter>(
{"LISTENER",
return std::make_unique<ListenerMetadataFormatter>(filter_namespace, path, max_length);
{"LISTENER_FILTER_CHAIN",
return std::make_unique<ListenerFilterChainMetadataFormatter>(filter_namespace, path,
max_length);
{"VIRTUAL_HOST",
return std::make_unique<VirtualHostMetadataFormatter>(filter_namespace, path,
});
::Envoy::Formatter::FormatterProviderPtr
MetadataFormatterCommandParser::parse(absl::string_view command, absl::string_view subcommand,
absl::optional<size_t> max_length) const {
if (command == "METADATA") {
// Extract type of metadata and keys.
absl::string_view type, filter_namespace;
std::vector<absl::string_view> path;
::Envoy::Formatter::SubstitutionFormatUtils::parseSubcommand(subcommand, ':', type,
filter_namespace, path);
auto provider = formatterProviderFuncTable().find(type);
if (provider == formatterProviderFuncTable().end()) {
throw EnvoyException(absl::StrCat(type, " is not supported type of metadata"));
// Return a pointer to formatter provider.
return provider->second(filter_namespace, path, max_length);
} // namespace Formatter
} // namespace Extensions
} // namespace Envoy