1
#pragma once
2

            
3
#include "envoy/event/timer.h"
4
#include "envoy/runtime/runtime.h"
5
#include "envoy/server/platform.h"
6

            
7
#include "source/common/common/thread.h"
8
#include "source/common/event/real_time_system.h"
9
#include "source/common/grpc/google_grpc_context.h"
10
#include "source/common/stats/symbol_table.h"
11
#include "source/common/stats/thread_local_store.h"
12
#include "source/common/thread_local/thread_local_impl.h"
13

            
14
#ifdef ENVOY_ADMIN_FUNCTIONALITY
15
#include "source/exe/admin_response.h"
16
#endif
17
#include "source/exe/process_wide.h"
18
#include "source/exe/stripped_main_base.h"
19
#include "source/server/listener_hooks.h"
20
#include "source/server/options_impl.h"
21
#include "source/server/server.h"
22

            
23
#ifdef ENVOY_HANDLE_SIGNALS
24
#include "source/common/signal/signal_action.h"
25
#include "source/exe/terminate_handler.h"
26
#endif
27

            
28
namespace Envoy {
29

            
30
class MainCommonBase : public StrippedMainBase {
31
public:
32
  MainCommonBase(const Server::Options& options, Event::TimeSystem& time_system,
33
                 ListenerHooks& listener_hooks, Server::ComponentFactory& component_factory,
34
                 std::unique_ptr<Server::Platform> platform_impl,
35
                 std::unique_ptr<Random::RandomGenerator>&& random_generator,
36
                 std::unique_ptr<ProcessContext> process_context);
37

            
38
  bool run();
39

            
40
#ifdef ENVOY_ADMIN_FUNCTIONALITY
41
  using AdminRequestFn =
42
      std::function<void(const Http::ResponseHeaderMap& response_headers, absl::string_view body)>;
43

            
44
  /**
45
   * Makes an admin-console request by path, calling handler() when complete.
46
   * The caller can initiate this from any thread, but it posts the request
47
   * onto the main thread, so the handler is called asynchronously.
48
   *
49
   * This is designed to be called from downstream consoles, so they can access
50
   * the admin console information stream without opening up a network port.
51
   *
52
   * This should only be called while run() is active; ensuring this is the
53
   * responsibility of the caller.
54
   *
55
   * TODO(jmarantz): consider std::future for encapsulating this delayed request
56
   * semantics, rather than a handler callback.
57
   *
58
   * Consider using the 2-arg version of adminRequest, below, which enables
59
   * streaming of large responses one chunk at a time, without holding
60
   * potentially huge response text in memory.
61
   *
62
   * @param path_and_query the URL to send to admin, including any query params.
63
   * @param method the HTTP method: "GET" or "POST"
64
   * @param handler an async callback that will be sent the serialized headers
65
   *        and response.
66
   */
67
  void adminRequest(absl::string_view path_and_query, absl::string_view method,
68
                    const AdminRequestFn& handler);
69

            
70
  /**
71
   * Initiates a streaming response to an admin request. The caller interacts
72
   * with the returned AdminResponse object, and can thus control the pace of
73
   * handling chunks of response text.
74
   *
75
   * @param path_and_query the URL to send to admin, including any query params.
76
   * @param method the HTTP method: "GET" or "POST"
77
   * @return AdminResponseSharedPtr the response object
78
   */
79
  AdminResponseSharedPtr adminRequest(absl::string_view path_and_query, absl::string_view method);
80

            
81
private:
82
  AdminResponse::SharedPtrSet shared_response_set_;
83
#endif
84
};
85

            
86
// This is separate from MainCommonBase for legacy reasons: sufficient
87
// downstream tests use one or the other that resolving is deemed problematic.
88
class MainCommon {
89
public:
90
  // Hook to run after a server is created.
91
  using PostServerHook = std::function<void(Server::Instance& server)>;
92

            
93
  MainCommon(int argc, const char* const* argv);
94
  MainCommon(const std::vector<std::string>& args);
95

            
96
32
  bool run() { return base_.run(); }
97
  // Only tests have a legitimate need for this today.
98
14
  Event::Dispatcher& dispatcherForTest() { return base_.server()->dispatcher(); }
99

            
100
#ifdef ENVOY_ADMIN_FUNCTIONALITY
101
  // Makes an admin-console request by path, calling handler() when complete.
102
  // The caller can initiate this from any thread, but it posts the request
103
  // onto the main thread, so the handler is called asynchronously.
104
  //
105
  // This is designed to be called from downstream consoles, so they can access
106
  // the admin console information stream without opening up a network port.
107
  //
108
  // This should only be called while run() is active; ensuring this is the
109
  // responsibility of the caller.
110
  void adminRequest(absl::string_view path_and_query, absl::string_view method,
111
31
                    const MainCommonBase::AdminRequestFn& handler) {
112
31
    base_.adminRequest(path_and_query, method, handler);
113
31
  }
114
21
  AdminResponseSharedPtr adminRequest(absl::string_view path_and_query, absl::string_view method) {
115
21
    return base_.adminRequest(path_and_query, method);
116
21
  }
117
#endif
118

            
119
  static std::string hotRestartVersion(bool hot_restart_enabled);
120

            
121
  /**
122
   * @return a pointer to the server instance, or nullptr if initialized into
123
   *         validation mode.
124
   */
125
22
  Server::Instance* server() { return base_.server(); }
126

            
127
  /**
128
   * Instantiates a MainCommon using default factory implements, parses args,
129
   * and runs an event loop depending on the mode.
130
   *
131
   * Note that MainCommonBase can also be directly instantiated, providing the
132
   * opportunity to override subsystem implementations for custom
133
   * implementations.
134
   *
135
   * @param argc number of command-line args
136
   * @param argv command-line argument array
137
   * @param hook optional hook to run after a server is created
138
   */
139
  static int main(int argc, char** argv, PostServerHook hook = nullptr);
140

            
141
private:
142
  Thread::MainThread main_thread_;
143

            
144
#ifdef ENVOY_HANDLE_SIGNALS
145
  Envoy::SignalAction handle_sigs_;
146
  Envoy::TerminateHandler log_on_terminate_;
147
#endif
148

            
149
  Envoy::OptionsImpl options_;
150
  Event::RealTimeSystem real_time_system_;
151
  DefaultListenerHooks default_listener_hooks_;
152
  ProdComponentFactory prod_component_factory_;
153
  MainCommonBase base_;
154
};
155

            
156
} // namespace Envoy