1
#pragma once
2

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

            
6
#include "envoy/common/random_generator.h"
7
#include "envoy/config/subscription.h"
8
#include "envoy/event/dispatcher.h"
9
#include "envoy/runtime/runtime.h"
10
#include "envoy/upstream/cluster_manager.h"
11

            
12
namespace Envoy {
13
namespace Http {
14

            
15
/**
16
 * A helper base class used to fetch a REST API at a jittered periodic interval. Once initialize()
17
 * is called, the API will be fetched and events raised.
18
 */
19
class RestApiFetcher : public Http::AsyncClient::Callbacks {
20
protected:
21
  RestApiFetcher(Upstream::ClusterManager& cm, const std::string& remote_cluster_name,
22
                 Event::Dispatcher& dispatcher, Random::RandomGenerator& random,
23
                 std::chrono::milliseconds refresh_interval,
24
                 std::chrono::milliseconds request_timeout);
25
  ~RestApiFetcher() override;
26

            
27
  /**
28
   * Start the fetch sequence. This should be called once.
29
   */
30
  void initialize();
31

            
32
  /**
33
   * This will be called when a fetch is about to happen. It should be overridden to fill the
34
   * request message with a valid request.
35
   */
36
  virtual void createRequest(RequestMessage& request) PURE;
37

            
38
  /**
39
   * This will be called when a 200 response is returned by the API with the response message.
40
   */
41
  virtual void parseResponse(const ResponseMessage& response) PURE;
42

            
43
  /**
44
   * This will be called either in the success case or in the failure case for each fetch. It can
45
   * be used to hold common post request logic.
46
   */
47
  virtual void onFetchComplete() PURE;
48

            
49
  /**
50
   * This will be called if the fetch fails (either due to non-200 response, network error, etc.).
51
   * @param reason supplies the fetch failure reason.
52
   * @param e supplies any exception data on why the fetch failed. May be nullptr.
53
   */
54
  virtual void onFetchFailure(Config::ConfigUpdateFailureReason reason,
55
                              const EnvoyException* e) PURE;
56

            
57
protected:
58
  const std::string remote_cluster_name_;
59
  Upstream::ClusterManager& cm_;
60

            
61
private:
62
  void refresh();
63
  void requestComplete();
64

            
65
  // Http::AsyncClient::Callbacks
66
  void onSuccess(const Http::AsyncClient::Request&, Http::ResponseMessagePtr&& response) override;
67
  void onFailure(const Http::AsyncClient::Request&,
68
                 Http::AsyncClient::FailureReason reason) override;
69
  void onBeforeFinalizeUpstreamSpan(Envoy::Tracing::Span&,
70
                                    const Http::ResponseHeaderMap*) override {}
71

            
72
  Random::RandomGenerator& random_;
73
  const std::chrono::milliseconds refresh_interval_;
74
  const std::chrono::milliseconds request_timeout_;
75
  Event::TimerPtr refresh_timer_;
76
  Http::AsyncClient::Request* active_request_{};
77
};
78

            
79
} // namespace Http
80
} // namespace Envoy