MySQL 9.3.0
Source Code Documentation
endpoint_base.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2024, 2025, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef ROUTER_SRC_MYSQL_REST_SERVICE_INCLUDE_MRS_INTERFACE_ENDPOINT_BASE_H_
27#define ROUTER_SRC_MYSQL_REST_SERVICE_INCLUDE_MRS_INTERFACE_ENDPOINT_BASE_H_
28
29#include <map>
30#include <memory>
31#include <mutex>
32#include <shared_mutex>
33#include <vector>
34
35#include "http/base/uri.h"
40
42
44
45namespace mrs {
46namespace interface {
47
48/*
49 * Base class to build the Endpoint hierarchy
50 *
51 * Following step should be done manually by
52 * the instance user.
53 * change_parent({});
54 * It's important because parent holds the pointer to this instance in
55 * endpoints_ /shared_ptr/.
56 */
57class EndpointBase : public std::enable_shared_from_this<EndpointBase> {
58 public:
60 using EndpointBasePtr = std::shared_ptr<EndpointBase>;
62 using Children = std::vector<EndpointBasePtr>;
64 using EndpointConfigurationPtr = std::shared_ptr<EndpointConfiguration>;
66 using HandlerPtr = std::shared_ptr<Handler>;
68 using OptionalIndexNames = std::optional<std::vector<std::string>>;
69
70 public:
72 : configuration_{configuration} {}
73 virtual ~EndpointBase() = default;
74
75 /*
76 * Virtual methods, to overwrite in subclass.
77 */
78 public:
79 virtual UniversalId get_id() const = 0;
80 virtual UniversalId get_parent_id() const = 0;
82
83 protected:
85 virtual std::string get_my_url_path_part() const = 0;
86 virtual std::string get_my_url_part() const = 0;
87 virtual bool does_this_node_require_authentication() const = 0;
88 virtual std::optional<std::string> get_options() const = 0;
89
90 /*
91 * Predefined behaviors.
92 */
93 public:
94 virtual bool required_authentication() const {
95 bool parents_required_authnetication = false;
96 auto parent = get_parent_ptr();
97
98 if (parent) {
99 parents_required_authnetication = parent->required_authentication();
100 }
101
102 return parents_required_authnetication ||
103 does_this_node_require_authentication();
104 }
105
106 virtual std::string get_url_path() const {
107 auto parent = get_parent_ptr();
108
109 return (parent ? parent->get_url_path() : std::string()) +
110 get_my_url_path_part();
111 }
112
113 virtual Uri get_url() const {
114 auto parent = get_parent_ptr();
115 Uri uri{parent ? parent->get_url() : Uri{}};
116 uri.set_path(uri.get_path() + get_my_url_part());
117
118 return uri;
119 }
120
121 /*
122 * enable-public
123 *
124 * The 'override' methods may expose handlers (http endpoints) that
125 * should be visible/available through HTTP interface.
126 */
127 virtual void activate_public() {}
128
129 /*
130 * enable-private
131 *
132 * The 'override' methods may initialize some per endpoint
133 * data that may be used internally in dependencies from other endpoints.
134 */
135 virtual void activate_private() {}
136
137 /*
138 * disable / deactivate
139 *
140 * The endpoint is still in memory, be should no
141 * expose any handlers (http endpoint) nor should be
142 * used internally.
143 */
144 virtual void deactivate() {}
145
147 auto parent = get_parent_ptr();
148
149 if (!parent) return EnabledType::EnabledType_none;
150
151 auto this_enabled_level = get_this_node_enabled_level();
152
153 if (this_enabled_level == EnabledType::EnabledType_none)
155
156 auto parent_enabled_level = parent->get_enabled_level();
157
158 if (this_enabled_level == EnabledType::EnabledType_public)
159 return parent_enabled_level;
160
161 return parent_enabled_level == EnabledType::EnabledType_public
163 : parent_enabled_level;
164 }
165
167 auto lock = std::unique_lock<std::shared_mutex>(endpoints_access_);
168 change_parent(parent);
169 changed();
170 }
171
173 auto parent_old = get_parent_ptr();
174
175 if (parent_old == parent_new) return;
176 if (parent_old) parent_old->remove_child_endpoint(get_id());
177 if (parent_new) parent_new->add_child_endpoint(shared_from_this());
178
179 parent_ = parent_new;
180 }
181
182 EndpointConfigurationPtr get_configuration() const { return configuration_; }
183
184 const EndpointBasePtr get_parent_ptr() const { return parent_.lock(); }
185 EndpointBasePtr get_parent_ptr() { return parent_.lock(); }
186
188 auto lock = std::unique_lock<std::shared_mutex>(endpoints_access_);
189
190 endpoints_.insert_or_assign(child_ptr->get_id(), child_ptr);
191 }
192
193 void remove_child_endpoint(const UniversalId &child_id) {
194 auto lock = std::unique_lock<std::shared_mutex>(endpoints_access_);
195 endpoints_.erase(child_id);
196 }
197
200 result.reserve(endpoints_.size());
201 for (auto [_, child] : endpoints_) {
202 result.push_back(child);
203 }
204
205 return result;
206 }
207
208 /*
209 * Generic methods
210 */
211 protected:
212 std::optional<EnabledType> last_state_;
213 static const char *get_state_name(EnabledType et) {
214 switch (et) {
216 return "disabled";
218 return "private";
220 return "public";
221 }
222 assert(false && "Missing 'enums' value inside the switch.");
223 return "unknown";
224 }
225 void log_update() {
226 auto current = get_enabled_level();
227 if (last_state_ != current) {
228 last_state_ = current;
229
230 log_info("Endpoint(id=%s, path='%s'%s) changed state to '%s'",
231 get_id().to_string().c_str(), get_url().join().c_str(),
232 get_extra_update_data().c_str(), get_state_name(current));
233 }
234 }
235
236 virtual std::string get_extra_update_data() { return {}; }
237
238 virtual void update() {
239 log_update();
240 switch (get_enabled_level()) {
242 activate_public();
243 break;
245 activate_private();
246 break;
248 deactivate();
249 break;
250 }
251 }
252
254 auto it = endpoints_.find(id);
255 if (it == endpoints_.end()) return {};
256
257 return it->second;
258 }
259
260 /*
261 * Update current endpoint and all its children
262 *
263 * Until now the method was called from other methods like:
264 * `change_parent`, `set`. This was changed because too many
265 * updates were generated. Currently, the user of the class
266 * is responsible to call `changed` in right moment.
267 */
268 void changed() {
269 update();
270 // Make a copy of shared-pointers that hold our children.
271 // This way we can operate in thread safe way.
272 auto children = get_children();
273
274 for (auto &child : children) child->changed();
275 }
276
277 protected:
278 std::shared_mutex endpoints_access_;
279 std::map<UniversalId, EndpointBasePtr> endpoints_;
280 std::weak_ptr<EndpointBase> parent_;
282};
283
284} // namespace interface
285} // namespace mrs
286
287#endif /* ROUTER_SRC_MYSQL_REST_SERVICE_INCLUDE_MRS_INTERFACE_ENDPOINT_BASE_H_ \
288 */
Definition: uri.h:40
virtual void set_path(const std::string &path)
Definition: uri.cc:162
Definition: endpoint_base.h:57
EndpointBasePtr get_parent_ptr()
Definition: endpoint_base.h:185
std::optional< std::vector< std::string > > OptionalIndexNames
Definition: endpoint_base.h:68
virtual std::string get_extra_update_data()
Definition: endpoint_base.h:236
void changed()
Definition: endpoint_base.h:268
virtual void activate_private()
Definition: endpoint_base.h:135
virtual UniversalId get_parent_id() const =0
virtual OptionalIndexNames get_index_files()=0
const EndpointBasePtr get_parent_ptr() const
Definition: endpoint_base.h:184
std::optional< EnabledType > last_state_
Definition: endpoint_base.h:212
EndpointBasePtr get_child_by_id(const UniversalId &id) const
Definition: endpoint_base.h:253
virtual UniversalId get_id() const =0
std::vector< EndpointBasePtr > Children
Definition: endpoint_base.h:62
mrs::database::entry::EnabledType EnabledType
Definition: endpoint_base.h:59
EndpointConfigurationPtr get_configuration() const
Definition: endpoint_base.h:182
virtual std::optional< std::string > get_options() const =0
virtual void update()
Definition: endpoint_base.h:238
virtual std::string get_my_url_path_part() const =0
void log_update()
Definition: endpoint_base.h:225
virtual std::string get_my_url_part() const =0
virtual void deactivate()
Definition: endpoint_base.h:144
void remove_child_endpoint(const UniversalId &child_id)
Definition: endpoint_base.h:193
std::weak_ptr< EndpointBase > parent_
Definition: endpoint_base.h:280
std::shared_mutex endpoints_access_
Definition: endpoint_base.h:278
std::map< UniversalId, EndpointBasePtr > endpoints_
Definition: endpoint_base.h:279
std::shared_ptr< EndpointBase > EndpointBasePtr
Definition: endpoint_base.h:60
void set_parent(EndpointBasePtr parent)
Definition: endpoint_base.h:166
EndpointBase(EndpointConfigurationPtr configuration)
Definition: endpoint_base.h:71
virtual bool does_this_node_require_authentication() const =0
virtual EnabledType get_enabled_level() const
Definition: endpoint_base.h:146
static const char * get_state_name(EnabledType et)
Definition: endpoint_base.h:213
virtual std::string get_url_path() const
Definition: endpoint_base.h:106
mrs::database::entry::UniversalId UniversalId
Definition: endpoint_base.h:61
virtual void activate_public()
Definition: endpoint_base.h:127
virtual Uri get_url() const
Definition: endpoint_base.h:113
EndpointConfigurationPtr configuration_
Definition: endpoint_base.h:281
void change_parent(EndpointBasePtr parent_new)
Definition: endpoint_base.h:172
void add_child_endpoint(EndpointBasePtr child_ptr)
Definition: endpoint_base.h:187
virtual bool required_authentication() const
Definition: endpoint_base.h:94
std::shared_ptr< Handler > HandlerPtr
Definition: endpoint_base.h:66
virtual ~EndpointBase()=default
std::shared_ptr< EndpointConfiguration > EndpointConfigurationPtr
Definition: endpoint_base.h:64
virtual EnabledType get_this_node_enabled_level() const =0
Children get_children()
Definition: endpoint_base.h:198
Definition: endpoint_configuration.h:35
Definition: rest_handler.h:135
#define log_info(...)
Definition: log_client.h:153
static std::string to_string(const LEX_STRING &str)
Definition: lex_string.h:50
Logging interface for using and extending the logging subsystem.
#define IMPORT_LOG_FUNCTIONS()
convenience macro to avoid common boilerplate
Definition: logging.h:323
static uint update
Definition: myisamlog.cc:94
Request::Uri Uri
Definition: request.cc:36
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:79
EnabledType
Definition: entry.h:56
@ EnabledType_private
Definition: entry.h:59
@ EnabledType_none
Definition: entry.h:57
@ EnabledType_public
Definition: entry.h:58
DbServiceEndpoint::EndpointConfiguration EndpointConfiguration
Definition: db_service_endpoint.cc:48
Definition: authorize_manager.h:48
mrs::database::entry::UniversalId UniversalId
Definition: universal_id.h:33
std::string join(const detail::range auto &rng, std::string_view delim)
join elements of a range into a string separated by a delimiter.
Definition: string.h:74
pid_type get_id()
Definition: process.h:48
struct result result
Definition: result.h:34
required string configuration
Definition: replication_asynchronous_connection_failover.proto:49
Definition: result.h:30
static task_env * deactivate(task_env *t)
Definition: task.cc:564
#define _(str)
Definition: win_i18n.h:33