1
#pragma once
2

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

            
6
#include "envoy/common/exception.h"
7
#include "envoy/common/optref.h"
8
#include "envoy/common/pure.h"
9
#include "envoy/service/discovery/v3/discovery.pb.h"
10
#include "envoy/stats/stats_macros.h"
11

            
12
#include "source/common/protobuf/protobuf.h"
13

            
14
namespace Envoy {
15
namespace Config {
16

            
17
/**
18
 * Reason that a config update is failed.
19
 */
20
enum class ConfigUpdateFailureReason {
21
  // A connection failure took place and the update could not be fetched.
22
  ConnectionFailure,
23
  // Config fetch timed out.
24
  FetchTimedout,
25
  // Update rejected because there is a problem in applying the update.
26
  UpdateRejected
27
};
28

            
29
/**
30
 * A wrapper for xDS resources that have been deserialized from the wire.
31
 */
32
class DecodedResource {
33
public:
34
15518
  virtual ~DecodedResource() = default;
35

            
36
  /**
37
   * @return const std::string& resource name.
38
   */
39
  virtual const std::string& name() const PURE;
40

            
41
  /**
42
   * @return const std::vector<std::string& resource aliases.
43
   */
44
  virtual const std::vector<std::string>& aliases() const PURE;
45

            
46
  /**
47
   * @return const std::string& resource version.
48
   */
49
  virtual const std::string& version() const PURE;
50

            
51
  /**
52
   * @return const Protobuf::Message& resource message reference. If hasResource() is false, this
53
   *         will be the empty message.
54
   */
55
  virtual const Protobuf::Message& resource() const PURE;
56

            
57
  virtual absl::optional<std::chrono::milliseconds> ttl() const PURE;
58

            
59
  /**
60
   * @return bool does the xDS discovery response have a set resource payload?
61
   */
62
  virtual bool hasResource() const PURE;
63

            
64
  /**
65
   * @return optional ref<envoy::config::core::v3::Metadata> of a resource.
66
   */
67
  virtual const OptRef<const envoy::config::core::v3::Metadata> metadata() const PURE;
68
};
69

            
70
using DecodedResourcePtr = std::unique_ptr<DecodedResource>;
71
using DecodedResourceRef = std::reference_wrapper<DecodedResource>;
72

            
73
class OpaqueResourceDecoder {
74
public:
75
13794
  virtual ~OpaqueResourceDecoder() = default;
76

            
77
  /**
78
   * @param resource some opaque resource (Protobuf::Any).
79
   * @return ProtobufTypes::MessagePtr decoded protobuf message in the opaque resource, e.g. the
80
   *         RouteConfiguration for an Any containing envoy.config.route.v3.RouteConfiguration.
81
   */
82
  virtual ProtobufTypes::MessagePtr decodeResource(const Protobuf::Any& resource) PURE;
83

            
84
  /**
85
   * @param resource some opaque resource (Protobuf::Message).
86
   * @return std::String the resource name in a Protobuf::Message returned by decodeResource(), e.g.
87
   *         the route config name for a envoy.config.route.v3.RouteConfiguration message.
88
   */
89
  virtual std::string resourceName(const Protobuf::Message& resource) PURE;
90
};
91

            
92
using OpaqueResourceDecoderSharedPtr = std::shared_ptr<OpaqueResourceDecoder>;
93

            
94
/**
95
 * Subscription to DecodedResources.
96
 */
97
class SubscriptionCallbacks {
98
public:
99
16241
  virtual ~SubscriptionCallbacks() = default;
100

            
101
  /**
102
   * Called when a state-of-the-world configuration update is received. (State-of-the-world is
103
   * everything other than delta gRPC - filesystem, HTTP, non-delta gRPC).
104
   * @param resources vector of fetched resources corresponding to the configuration update.
105
   * @param version_info supplies the version information as supplied by the xDS discovery response.
106
   * @return an absl status indicating if a non-exception-throwing error was encountered.
107
   * @throw EnvoyException with reason if the configuration is rejected for legacy reasons,
108
   *        Accepted configurations have their version_info reflected in subsequent requests.
109
   */
110
  virtual absl::Status onConfigUpdate(const std::vector<DecodedResourceRef>& resources,
111
                                      const std::string& version_info) PURE;
112

            
113
  /**
114
   * Called when a delta configuration update is received.
115
   * @param added_resources resources newly added since the previous fetch.
116
   * @param removed_resources names of resources that this fetch instructed to be removed.
117
   * @param system_version_info aggregate response data "version", for debugging.
118
   * @return an absl status indicating if a non-exception-throwing error was encountered.
119
   * @throw EnvoyException with reason if the configuration is rejected for legacy reasons,
120
   *        Accepted configurations have their version_info reflected in subsequent requests.
121
   */
122
  virtual absl::Status
123
  onConfigUpdate(const std::vector<DecodedResourceRef>& added_resources,
124
                 const Protobuf::RepeatedPtrField<std::string>& removed_resources,
125
                 const std::string& system_version_info) PURE;
126

            
127
  /**
128
   * Called when either the Subscription is unable to fetch a config update or when onConfigUpdate
129
   * returns a failure or invokes an exception.
130
   * @param reason supplies the update failure reason.
131
   * @param e supplies any exception data on why the fetch failed. May be nullptr.
132
   */
133
  virtual void onConfigUpdateFailed(ConfigUpdateFailureReason reason, const EnvoyException* e) PURE;
134
};
135

            
136
/**
137
 * Options associated with a Subscription.
138
 */
139
struct SubscriptionOptions {
140
  /**
141
   * For legacy VHDS, should an xDS resource name be treated as <namespace>/<resource name>? This is
142
   * incompatible with the use of xdstp:// naming.
143
   */
144
  bool use_namespace_matching_{};
145

            
146
  /**
147
   * For xdstp:// resource names, should node context parameters be added at the transport layer?
148
   */
149
  bool add_xdstp_node_context_params_{};
150
};
151

            
152
/**
153
 * Invoked when raw config received from xDS wire.
154
 */
155
class UntypedConfigUpdateCallbacks {
156
public:
157
1354
  virtual ~UntypedConfigUpdateCallbacks() = default;
158

            
159
  // TODO (dmitri-d) remove this method when legacy sotw mux has been removed.
160
  /**
161
   * Called when a state-of-the-world configuration update is received. (State-of-the-world is
162
   * everything other than delta gRPC - filesystem, HTTP, non-delta gRPC).
163
   * @param resources vector of fetched resources corresponding to the configuration update.
164
   * @param version_info supplies the version information as supplied by the xDS discovery response.
165
   * @throw EnvoyException with reason if the configuration is rejected. Otherwise the configuration
166
   *        is accepted. Accepted configurations have their version_info reflected in subsequent
167
   *        requests.
168
   */
169
  virtual void onConfigUpdate(const Protobuf::RepeatedPtrField<Protobuf::Any>& resources,
170
                              const std::string& version_info) PURE;
171

            
172
  /**
173
   * Called when a non-delta gRPC configuration update is received.
174
   * @param resources vector of fetched resources corresponding to the configuration update.
175
   * @param version_info supplies the version information as supplied by the xDS discovery response.
176
   * @throw EnvoyException with reason if the configuration is rejected. Otherwise the configuration
177
   *        is accepted. Accepted configurations have their version_info reflected in subsequent
178
   *        requests.
179
   */
180
  virtual void onConfigUpdate(const std::vector<DecodedResourcePtr>& resources,
181
                              const std::string& version_info) PURE;
182

            
183
  /**
184
   * Called when a delta configuration update is received.
185
   * @param added_resources resources newly added since the previous fetch.
186
   * @param removed_resources names of resources that this fetch instructed to be removed.
187
   * @param system_version_info aggregate response data "version", for debugging.
188
   * @throw EnvoyException with reason if the config changes are rejected. Otherwise the changes
189
   * @param use_namespace_matching if the resources should me matched on their namespaces, rather
190
   * than unique names. This is used when a collection of resources (e.g. virtual hosts in VHDS) is
191
   * being updated. Accepted changes have their version_info reflected in subsequent
192
   * requests.
193
   */
194
  virtual void
195
  onConfigUpdate(absl::Span<const envoy::service::discovery::v3::Resource* const> added_resources,
196
                 const Protobuf::RepeatedPtrField<std::string>& removed_resources,
197
                 const std::string& system_version_info) PURE;
198

            
199
  /**
200
   * Called when either the Subscription is unable to fetch a config update or when onConfigUpdate
201
   * invokes an exception.
202
   * @param reason supplies the update failure reason.
203
   * @param e supplies any exception data on why the fetch failed. May be nullptr.
204
   */
205
  virtual void onConfigUpdateFailed(ConfigUpdateFailureReason reason, const EnvoyException* e) PURE;
206
};
207

            
208
/**
209
 * Common abstraction for subscribing to versioned config updates. This may be implemented via bidi
210
 * gRPC streams, periodic/long polling REST or inotify filesystem updates.
211
 */
212
class Subscription {
213
public:
214
13289
  virtual ~Subscription() = default;
215

            
216
  /**
217
   * Start a configuration subscription asynchronously. This should be called once and will continue
218
   * to fetch throughout the lifetime of the Subscription object.
219
   * @param resources set of resource names to fetch.
220
   */
221
  virtual void start(const absl::flat_hash_set<std::string>& resource_names) PURE;
222

            
223
  /**
224
   * Update the resources to fetch.
225
   * @param resources vector of resource names to fetch.
226
   */
227
  virtual void
228
  updateResourceInterest(const absl::flat_hash_set<std::string>& update_to_these_names) PURE;
229

            
230
  /**
231
   * Creates a discovery request for resources.
232
   * @param add_these_names resource ids for inclusion in the discovery request.
233
   */
234
  virtual void requestOnDemandUpdate(const absl::flat_hash_set<std::string>& add_these_names) PURE;
235
};
236

            
237
using SubscriptionPtr = std::unique_ptr<Subscription>;
238

            
239
/**
240
 * Per subscription stats. @see stats_macros.h
241
 */
242
#define ALL_SUBSCRIPTION_STATS(COUNTER, GAUGE, TEXT_READOUT, HISTOGRAM)                            \
243
12896
  COUNTER(init_fetch_timeout)                                                                      \
244
12896
  COUNTER(update_attempt)                                                                          \
245
12896
  COUNTER(update_failure)                                                                          \
246
12896
  COUNTER(update_rejected)                                                                         \
247
12896
  COUNTER(update_success)                                                                          \
248
12896
  GAUGE(update_time, NeverImport)                                                                  \
249
12896
  GAUGE(version, NeverImport)                                                                      \
250
12896
  HISTOGRAM(update_duration, Milliseconds)                                                         \
251
12896
  TEXT_READOUT(version_text)
252

            
253
/**
254
 * Struct definition for per subscription stats. @see stats_macros.h
255
 */
256
struct SubscriptionStats {
257
  ALL_SUBSCRIPTION_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT,
258
                         GENERATE_TEXT_READOUT_STRUCT, GENERATE_HISTOGRAM_STRUCT)
259
};
260

            
261
} // namespace Config
262
} // namespace Envoy