Line data Source code
1 : #pragma once 2 : 3 : #include <string> 4 : 5 : #include "envoy/api/api.h" 6 : #include "envoy/config/core/v3/substitution_format_string.pb.h" 7 : #include "envoy/formatter/substitution_formatter.h" 8 : #include "envoy/server/factory_context.h" 9 : 10 : #include "source/common/config/datasource.h" 11 : #include "source/common/config/utility.h" 12 : #include "source/common/formatter/substitution_formatter.h" 13 : #include "source/common/protobuf/message_validator_impl.h" 14 : #include "source/common/protobuf/protobuf.h" 15 : #include "source/server/generic_factory_context.h" 16 : 17 : namespace Envoy { 18 : namespace Formatter { 19 : 20 : /** 21 : * Utilities for using envoy::config::core::v3::SubstitutionFormatString 22 : */ 23 : class SubstitutionFormatStringUtils { 24 : public: 25 : /** 26 : * Generate a formatter object from config SubstitutionFormatString. 27 : */ 28 : template <class FormatterContext = HttpFormatterContext> 29 : static FormatterBasePtr<FormatterContext> 30 : fromProtoConfig(const envoy::config::core::v3::SubstitutionFormatString& config, 31 1 : Server::Configuration::GenericFactoryContext& context) { 32 : // Instantiate formatter extensions. 33 1 : std::vector<CommandParserBasePtr<FormatterContext>> commands; 34 1 : for (const auto& formatter : config.formatters()) { 35 0 : auto* factory = 36 0 : Envoy::Config::Utility::getFactory<CommandParserFactoryBase<FormatterContext>>(formatter); 37 0 : if (!factory) { 38 0 : throwEnvoyExceptionOrPanic(absl::StrCat("Formatter not found: ", formatter.name())); 39 0 : } 40 0 : auto typed_config = Envoy::Config::Utility::translateAnyToFactoryConfig( 41 0 : formatter.typed_config(), context.messageValidationVisitor(), *factory); 42 0 : auto parser = factory->createCommandParserFromProto(*typed_config, context); 43 0 : if (!parser) { 44 0 : throwEnvoyExceptionOrPanic( 45 0 : absl::StrCat("Failed to create command parser: ", formatter.name())); 46 0 : } 47 0 : commands.push_back(std::move(parser)); 48 0 : } 49 : 50 1 : switch (config.format_case()) { 51 0 : case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kTextFormat: 52 0 : return std::make_unique<FormatterBaseImpl<FormatterContext>>( 53 0 : config.text_format(), config.omit_empty_values(), commands); 54 1 : case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kJsonFormat: 55 1 : return std::make_unique<JsonFormatterBaseImpl<FormatterContext>>( 56 1 : config.json_format(), true, config.omit_empty_values(), 57 1 : config.has_json_format_options() ? config.json_format_options().sort_properties() : false, 58 1 : commands); 59 0 : case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kTextFormatSource: 60 0 : return std::make_unique<FormatterBaseImpl<FormatterContext>>( 61 0 : Config::DataSource::read(config.text_format_source(), true, 62 0 : context.serverFactoryContext().api()), 63 0 : config.omit_empty_values(), commands); 64 0 : case envoy::config::core::v3::SubstitutionFormatString::FormatCase::FORMAT_NOT_SET: 65 0 : PANIC_DUE_TO_PROTO_UNSET; 66 1 : } 67 : 68 0 : return nullptr; 69 1 : } 70 : 71 : /** 72 : * Generate a Json formatter object from proto::Struct config 73 : */ 74 : template <class FormatterContext = HttpFormatterContext> 75 : static FormatterBasePtr<FormatterContext> 76 : createJsonFormatter(const ProtobufWkt::Struct& struct_format, bool preserve_types, 77 0 : bool omit_empty_values, bool sort_properties) { 78 0 : return std::make_unique<JsonFormatterBaseImpl<FormatterContext>>( 79 0 : struct_format, preserve_types, omit_empty_values, sort_properties); 80 0 : } 81 : }; 82 : 83 : } // namespace Formatter 84 : } // namespace Envoy