1
#pragma once
2

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

            
7
#include "envoy/config/cluster/v3/cluster.pb.h"
8
#include "envoy/config/cluster/v3/cluster.pb.validate.h"
9
#include "envoy/config/core/v3/config_source.pb.h"
10
#include "envoy/config/subscription.h"
11
#include "envoy/protobuf/message_validator.h"
12
#include "envoy/server/factory_context.h"
13
#include "envoy/stats/scope.h"
14
#include "envoy/upstream/cluster_manager.h"
15

            
16
#include "source/common/config/subscription_base.h"
17
#include "source/common/protobuf/protobuf.h"
18
#include "source/common/upstream/cds_api_helper.h"
19

            
20
namespace Envoy {
21
namespace Upstream {
22

            
23
#define ALL_CDS_STATS(COUNTER, GAUGE)                                                              \
24
730
  COUNTER(config_reload)                                                                           \
25
730
  GAUGE(config_reload_time_ms, NeverImport)
26

            
27
struct CdsStats {
28
  ALL_CDS_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT)
29
};
30

            
31
/**
32
 * CDS API implementation that fetches via Subscription.
33
 * This supports the wildcard subscription to a single source.
34
 */
35
class CdsApiImpl : public CdsApi,
36
                   Envoy::Config::SubscriptionBase<envoy::config::cluster::v3::Cluster> {
37
public:
38
  static absl::StatusOr<CdsApiPtr>
39
  create(const envoy::config::core::v3::ConfigSource& cds_config,
40
         const xds::core::v3::ResourceLocator* cds_resources_locator, ClusterManager& cm,
41
         Stats::Scope& scope, ProtobufMessage::ValidationVisitor& validation_visitor,
42
         Server::Configuration::ServerFactoryContext& factory_context,
43
         bool support_multi_ads_sources);
44

            
45
  // Upstream::CdsApi
46
721
  void initialize() override { subscription_->start({}); }
47
725
  void setInitializedCb(std::function<void()> callback) override {
48
725
    initialize_callback_ = callback;
49
725
  }
50
38
  const std::string versionInfo() const override { return helper_.versionInfo(); }
51

            
52
private:
53
  // Config::SubscriptionCallbacks
54
  absl::Status onConfigUpdate(const std::vector<Config::DecodedResourceRef>& resources,
55
                              const std::string& version_info) override;
56
  absl::Status onConfigUpdate(const std::vector<Config::DecodedResourceRef>& added_resources,
57
                              const Protobuf::RepeatedPtrField<std::string>& removed_resources,
58
                              const std::string& system_version_info) override;
59
  void onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason,
60
                            const EnvoyException* e) override;
61
  CdsApiImpl(const envoy::config::core::v3::ConfigSource& cds_config,
62
             const xds::core::v3::ResourceLocator* cds_resources_locator, ClusterManager& cm,
63
             Stats::Scope& scope, ProtobufMessage::ValidationVisitor& validation_visitor,
64
             Server::Configuration::ServerFactoryContext& factory_context,
65
             bool support_multi_ads_sources, absl::Status& creation_status);
66
  void runInitializeCallbackIfAny();
67

            
68
  CdsApiHelper helper_;
69
  ClusterManager& cm_;
70
  Stats::ScopeSharedPtr scope_;
71
  Server::Configuration::ServerFactoryContext& factory_context_;
72
  CdsStats stats_;
73
  // This enables tracking the resources via SotW for wildcard-CDS, so concurrent OD-CDS
74
  // resources won't get overridden when a CDS-wildcard update arrives.
75
  // TODO(adisuissa): once proper support for an xDS-Caching layer is added,
76
  // this will not be relevant, as the callbacks will be similar to delta-xDS
77
  // from each collection source.
78
  const bool support_multi_ads_sources_;
79
  absl::flat_hash_set<std::string> sotw_resource_names_;
80
  Config::SubscriptionPtr subscription_;
81
  std::function<void()> initialize_callback_;
82
};
83

            
84
} // namespace Upstream
85
} // namespace Envoy