1
#pragma once
2

            
3
#include <vector>
4

            
5
#include "envoy/content_parser/factory.h"
6
#include "envoy/content_parser/parser.h"
7
#include "envoy/extensions/content_parsers/json/v3/json_content_parser.pb.h"
8
#include "envoy/json/json_object.h"
9

            
10
#include "source/common/common/logger.h"
11

            
12
#include "absl/status/statusor.h"
13

            
14
namespace Envoy {
15
namespace Extensions {
16
namespace ContentParsers {
17
namespace Json {
18

            
19
using ProtoRule = envoy::extensions::filters::http::json_to_metadata::v3::JsonToMetadata::Rule;
20
using KeyValuePair =
21
    envoy::extensions::filters::http::json_to_metadata::v3::JsonToMetadata::KeyValuePair;
22
using ValueType = envoy::extensions::filters::http::json_to_metadata::v3::JsonToMetadata::ValueType;
23
using Selector = envoy::extensions::filters::http::json_to_metadata::v3::JsonToMetadata::Selector;
24

            
25
/**
26
 * Parses JSON content extracts metadata based on JSON path selectors.
27
 */
28
class JsonContentParserImpl : public ContentParser::Parser,
29
                              public Logger::Loggable<Logger::Id::filter> {
30
public:
31
  JsonContentParserImpl(
32
      const envoy::extensions::content_parsers::json::v3::JsonContentParser& config);
33

            
34
  ContentParser::ParseResult parse(absl::string_view data) override;
35
  std::vector<ContentParser::MetadataAction> getAllDeferredActions() override;
36

            
37
private:
38
  class Rule {
39
  public:
40
    Rule(const ProtoRule& rule, uint32_t stop_processing_after_matches);
41
    const ProtoRule& rule_;
42
    std::vector<std::string> selector_path_;
43
    uint32_t stop_processing_after_matches_;
44
    size_t match_count_ = 0;
45
    bool ever_matched_ = false;       // Track if on_present ever fired
46
    bool selector_not_found_ = false; // Track if selector was ever not found
47
  };
48

            
49
  // Session-level state (accumulated across parse() calls)
50
  bool any_parse_error_ = false;
51

            
52
  /**
53
   * Extract value from JSON object using path.
54
   */
55
  absl::StatusOr<Envoy::Json::ValueType>
56
  extractValueFromJson(const Envoy::Json::ObjectSharedPtr& json_obj,
57
                       const std::vector<std::string>& path) const;
58

            
59
  /**
60
   * Convert KeyValuePair to metadata action.
61
   */
62
  ContentParser::MetadataAction
63
  keyValuePairToAction(const KeyValuePair& kv_pair,
64
                       const absl::optional<Envoy::Json::ValueType>& extracted_value) const;
65

            
66
  /**
67
   * Convert JSON value to Protobuf::Value for metadata.
68
   */
69
  Protobuf::Value jsonValueToProtobufValue(const Envoy::Json::ValueType& value,
70
                                           ValueType type) const;
71

            
72
  std::vector<Rule> rules_;
73
};
74

            
75
/**
76
 * Factory for creating JSON content parser instances.
77
 */
78
class JsonContentParserFactory : public ContentParser::ParserFactory {
79
public:
80
  JsonContentParserFactory(
81
      const envoy::extensions::content_parsers::json::v3::JsonContentParser& config);
82

            
83
  ContentParser::ParserPtr createParser() override;
84
  const std::string& statsPrefix() const override;
85

            
86
private:
87
  const envoy::extensions::content_parsers::json::v3::JsonContentParser config_;
88
};
89

            
90
} // namespace Json
91
} // namespace ContentParsers
92
} // namespace Extensions
93
} // namespace Envoy