1
#pragma once
2

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

            
7
#include "envoy/config/core/v3/config_source.pb.h"
8
#include "envoy/config/route/v3/route_components.pb.h"
9
#include "envoy/config/route/v3/route_components.pb.validate.h"
10
#include "envoy/config/subscription.h"
11
#include "envoy/http/codes.h"
12
#include "envoy/local_info/local_info.h"
13
#include "envoy/router/rds.h"
14
#include "envoy/router/route_config_update_receiver.h"
15
#include "envoy/server/filter_config.h"
16
#include "envoy/service/discovery/v3/discovery.pb.h"
17
#include "envoy/singleton/instance.h"
18
#include "envoy/stats/scope.h"
19
#include "envoy/thread_local/thread_local.h"
20

            
21
#include "source/common/common/logger.h"
22
#include "source/common/config/subscription_base.h"
23
#include "source/common/init/target_impl.h"
24
#include "source/common/protobuf/utility.h"
25

            
26
#include "absl/container/node_hash_set.h"
27

            
28
namespace Envoy {
29
namespace Router {
30

            
31
#define ALL_VHDS_STATS(COUNTER)                                                                    \
32
43
  COUNTER(config_reload)                                                                           \
33
43
  COUNTER(update_empty)
34

            
35
struct VhdsStats {
36
  ALL_VHDS_STATS(GENERATE_COUNTER_STRUCT)
37
};
38

            
39
class VhdsSubscription : Envoy::Config::SubscriptionBase<envoy::config::route::v3::VirtualHost>,
40
                         Logger::Loggable<Logger::Id::router> {
41
public:
42
  static absl::StatusOr<std::unique_ptr<VhdsSubscription>>
43
  createVhdsSubscription(RouteConfigUpdatePtr& config_update_info,
44
                         Server::Configuration::ServerFactoryContext& factory_context,
45
                         const std::string& stat_prefix,
46
                         Rds::RouteConfigProvider* route_config_provider);
47

            
48
43
  ~VhdsSubscription() override { init_target_.ready(); }
49

            
50
39
  void registerInitTargetWithInitManager(Init::Manager& m) { m.add(init_target_); }
51
  void updateOnDemand(const std::string& with_route_config_name_prefix);
52
  static std::string domainNameToAlias(const std::string& route_config_name,
53
25
                                       const std::string& domain) {
54
25
    return route_config_name + "/" + domain;
55
25
  }
56
24
  static std::string aliasToDomainName(const std::string& alias) {
57
24
    const auto pos = alias.find_last_of('/');
58
24
    return pos == std::string::npos ? alias : alias.substr(pos + 1);
59
24
  }
60

            
61
private:
62
  VhdsSubscription(RouteConfigUpdatePtr& config_update_info,
63
                   Server::Configuration::ServerFactoryContext& factory_context,
64
                   const std::string& stat_prefix, Rds::RouteConfigProvider* route_config_provider,
65
                   absl::Status& creation_status);
66

            
67
  // Config::SubscriptionCallbacks
68
  absl::Status onConfigUpdate(const std::vector<Envoy::Config::DecodedResourceRef>&,
69
                              const std::string&) override {
70
    return absl::OkStatus();
71
  }
72
  absl::Status onConfigUpdate(const std::vector<Envoy::Config::DecodedResourceRef>&,
73
                              const Protobuf::RepeatedPtrField<std::string>&,
74
                              const std::string&) override;
75
  void onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason,
76
                            const EnvoyException* e) override;
77

            
78
  RouteConfigUpdatePtr& config_update_info_;
79
  Stats::ScopeSharedPtr scope_;
80
  VhdsStats stats_;
81
  Envoy::Config::SubscriptionPtr subscription_;
82
  Init::TargetImpl init_target_;
83
  Rds::RouteConfigProvider* route_config_provider_;
84
};
85

            
86
using VhdsSubscriptionPtr = std::unique_ptr<VhdsSubscription>;
87

            
88
} // namespace Router
89
} // namespace Envoy