1
#pragma once
2

            
3
#include <memory>
4
#include <string>
5

            
6
#include "envoy/common/pure.h"
7
#include "envoy/config/typed_config.h"
8

            
9
#include "source/common/protobuf/protobuf.h"
10

            
11
namespace Envoy {
12
namespace Config {
13

            
14
/**
15
 * TypedMetadata interface.
16
 */
17
class TypedMetadata {
18
public:
19
  class Object {
20
  public:
21
17827
    virtual ~Object() = default;
22
  };
23

            
24
41244
  virtual ~TypedMetadata() = default;
25

            
26
  /**
27
   * @return a T instance by key. If the conversion is not able to complete, or
28
   * if the data is not in the store, returns a nullptr.
29
   */
30
53
  template <typename T> const T* get(const std::string& key) const {
31
53
    static_assert(std::is_base_of<Object, T>::value,
32
53
                  "Data type must be subclass of TypedMetadata::Object");
33
53
    const Object* p = getData(key);
34
53
    if (p != nullptr) {
35
46
      return dynamic_cast<const T*>(p);
36
46
    }
37
7
    return nullptr;
38
53
  }
39

            
40
protected:
41
  /**
42
   * Returns data associated with given 'key'.
43
   * If there is no data associated with this key, a nullptr is returned.
44
   * @param key the key (usually a reversed DNS) associated with the typed metadata.
45
   * @return A TypedMetadata::Object pointer, nullptr if no data is associated with the key.
46
   */
47
  virtual const Object* getData(const std::string& key) const PURE;
48
};
49

            
50
/**
51
 * Typed metadata should implement this factory and register via Registry::registerFactory or the
52
 * convenience class RegisterFactory.
53
 */
54
class TypedMetadataFactory : public UntypedFactory {
55
public:
56
33
  ~TypedMetadataFactory() override = default;
57

            
58
  /**
59
   * Convert the google.protobuf.Struct into an instance of TypedMetadata::Object.
60
   * It should throw an EnvoyException in case the conversion can't be completed.
61
   * @param data config data stored as a protobuf struct.
62
   * @return a derived class object pointer of TypedMetadata.
63
   * @throw EnvoyException if the parsing can't be done.
64
   */
65
  virtual std::unique_ptr<const TypedMetadata::Object>
66
  parse(const Protobuf::Struct& data) const PURE;
67

            
68
  /**
69
   * Convert the google.protobuf.Any into an instance of TypedMetadata::Object.
70
   * It should throw an EnvoyException in case the conversion can't be completed.
71
   * @param data config data stored as a protobuf any.
72
   * @return a derived class object pointer of TypedMetadata or return nullptr if
73
   * one doesn't implement parse() method.
74
   * @throw EnvoyException if the parsing can't be done.
75
   */
76
  virtual std::unique_ptr<const TypedMetadata::Object> parse(const Protobuf::Any& data) const PURE;
77

            
78
46
  std::string category() const override { return "envoy.typed_metadata"; }
79
};
80

            
81
} // namespace Config
82
} // namespace Envoy