MySQL 8.0.39
Source Code Documentation
rest_api_component.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2019, 2024, 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 MYSQLROUTER_REST_API_COMPONENT_INCLUDED
27#define MYSQLROUTER_REST_API_COMPONENT_INCLUDED
28
29#include <mutex>
30
32
33#ifdef RAPIDJSON_NO_SIZETYPEDEFINE
34#include "my_rapidjson_size_t.h"
35#endif
36
37#include <rapidjson/document.h>
38#include <rapidjson/pointer.h>
39#include <rapidjson/prettywriter.h>
40#include <rapidjson/schema.h>
41
43
44class RestApi;
45
47 public:
48 BaseRestApiHandler() = default;
53 /**
54 * try to handle the request.
55 *
56 * @returns success
57 * @retval true request has been handled and a response has been sent
58 * @retval false request has not been handled (no response has been sent)
59 */
60 virtual bool try_handle_request(
61 HttpRequest &req, const std::string &base_path,
62 const std::vector<std::string> &path_matches) = 0;
63
65};
66
67/**
68 * handler for REST API calls.
69 *
70 * - may require authentication
71 * - enforces HTTP Methods
72 */
74 public:
75 RestApiHandler(const std::string &require_realm,
76 HttpMethod::Bitset allowed_methods)
77 : require_realm_(require_realm), allowed_methods_(allowed_methods) {}
78
79 bool try_handle_request(
80 HttpRequest &req, const std::string &base_path,
81 const std::vector<std::string> &path_matches) override;
82
83 virtual bool on_handle_request(
84 HttpRequest &req, const std::string &base_path,
85 const std::vector<std::string> &path_matches) = 0;
86
87 private:
88 std::string require_realm_;
89
91};
92
94 public:
95 // AddressSanitizer gets confused by the default, MemoryPoolAllocator
96 // Solaris sparc also gets crashes
98 rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator>;
99 using JsonValue =
100 rapidjson::GenericValue<rapidjson::UTF8<>, JsonDocument::AllocatorType>;
102 rapidjson::GenericPointer<JsonValue, JsonDocument::AllocatorType>;
103
104 /**
105 * get singleton instance of the component.
106 */
107 static RestApiComponent &get_instance();
108
109 /**
110 * initialize component.
111 *
112 * registers RestApi with the component and actives the processing of
113 * the backlogs for:
114 *
115 * - try_process_spec()
116 * - add_path()
117 */
118 void init(std::shared_ptr<RestApi> srv);
119
120 /**
121 * processor for the RestAPI's spec.
122 *
123 * @param spec_doc JSON document to modify
124 */
125 using SpecProcessor = void (*)(JsonDocument &spec_doc);
126
127 /**
128 * try to process the RestAPI's spec.
129 *
130 * if the component hasn't been initialized from the rest_api plugin yet,
131 * false is returned and the processor is added to a backlog which is
132 * processed when init() is called.
133 *
134 * As the rest_api may fail to load, the caller should remove itself again
135 * with remove_process_spec() in that case.
136 *
137 * That's not needed in case try_process_spec() returns true.
138 *
139 * @param processor document processor
140 * @returns success
141 * @retval true spec was processed.
142 * @retval false processor added to backlog.
143 */
144 bool try_process_spec(SpecProcessor processor);
145
146 /**
147 * remove processor from backlog if exists.
148 *
149 * @param processor document processor
150 */
151 void remove_process_spec(SpecProcessor processor);
152
153 /**
154 * added handler for a path.
155 *
156 * path must be unique
157 *
158 * @param path regex for the path
159 * @param handler handler for the path
160 */
161 void add_path(const std::string &path,
162 std::unique_ptr<BaseRestApiHandler> handler);
163
164 /**
165 * remove a path.
166 *
167 * must be called before the plugin gets unloaded that added the handler
168 * in the first place.
169 */
170 void remove_path(const std::string &path);
171
172 private:
173 // disable copy, as we are a single-instance
175 void operator=(RestApiComponent const &) = delete;
176
177 std::mutex spec_mu_; // backlog mutex mutex
178 std::vector<SpecProcessor> spec_processors_;
179 std::vector<std::pair<std::string, std::unique_ptr<BaseRestApiHandler>>>
181
182 std::weak_ptr<RestApi> srv_;
183
184 RestApiComponent() = default;
185};
186
187/**
188 * Helper class to make unregistering paths in plugins easier.
189 */
191 public:
192 RestApiComponentPath(RestApiComponent &rest_api_srv, std::string regex,
193 std::unique_ptr<BaseRestApiHandler> endpoint)
194 : rest_api_srv_{rest_api_srv}, regex_(std::move(regex)) {
195 rest_api_srv_.add_path(regex_, std::move(endpoint));
196 }
197
199 try {
201 } catch (...) {
202 // if it already is removed manually, ignore it
203 }
204 }
205
206 private:
208 std::string regex_;
209};
210
211#endif
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:571
Definition: rest_api_component.h:46
BaseRestApiHandler()=default
virtual ~BaseRestApiHandler()
virtual bool try_handle_request(HttpRequest &req, const std::string &base_path, const std::vector< std::string > &path_matches)=0
try to handle the request.
BaseRestApiHandler & operator=(const BaseRestApiHandler &)=default
BaseRestApiHandler(const BaseRestApiHandler &)=default
BaseRestApiHandler & operator=(BaseRestApiHandler &&)=default
BaseRestApiHandler(BaseRestApiHandler &&)=default
a HTTP request and response.
Definition: http_request.h:453
Helper class to make unregistering paths in plugins easier.
Definition: rest_api_component.h:190
~RestApiComponentPath()
Definition: rest_api_component.h:198
RestApiComponent & rest_api_srv_
Definition: rest_api_component.h:207
RestApiComponentPath(RestApiComponent &rest_api_srv, std::string regex, std::unique_ptr< BaseRestApiHandler > endpoint)
Definition: rest_api_component.h:192
std::string regex_
Definition: rest_api_component.h:208
Definition: rest_api_component.h:93
RestApiComponent(RestApiComponent const &)=delete
void(*)(JsonDocument &spec_doc) SpecProcessor
processor for the RestAPI's spec.
Definition: rest_api_component.h:125
rapidjson::GenericValue< rapidjson::UTF8<>, JsonDocument::AllocatorType > JsonValue
Definition: rest_api_component.h:100
RestApiComponent()=default
std::weak_ptr< RestApi > srv_
Definition: rest_api_component.h:182
void add_path(const std::string &path, std::unique_ptr< BaseRestApiHandler > handler)
added handler for a path.
Definition: rest_api_component.cc:63
void operator=(RestApiComponent const &)=delete
std::mutex spec_mu_
Definition: rest_api_component.h:177
void remove_path(const std::string &path)
remove a path.
Definition: rest_api_component.cc:76
std::vector< std::pair< std::string, std::unique_ptr< BaseRestApiHandler > > > add_path_backlog_
Definition: rest_api_component.h:180
rapidjson::GenericDocument< rapidjson::UTF8<>, rapidjson::CrtAllocator > JsonDocument
Definition: rest_api_component.h:98
std::vector< SpecProcessor > spec_processors_
Definition: rest_api_component.h:178
rapidjson::GenericPointer< JsonValue, JsonDocument::AllocatorType > JsonPointer
Definition: rest_api_component.h:102
handler for REST API calls.
Definition: rest_api_component.h:73
virtual bool on_handle_request(HttpRequest &req, const std::string &base_path, const std::vector< std::string > &path_matches)=0
HttpMethod::Bitset allowed_methods_
Definition: rest_api_component.h:90
RestApiHandler(const std::string &require_realm, HttpMethod::Bitset allowed_methods)
Definition: rest_api_component.h:75
std::string require_realm_
Definition: rest_api_component.h:88
Definition: rest_api_plugin.h:35
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4414
Define rapidjson::SizeType to be std::size_t.
static char * path
Definition: mysqldump.cc:137
std::bitset< Pos::_LAST+1 > Bitset
Definition: http_request.h:268
Definition: srv0dynamic_procedures.h:48
Definition: gcs_xcom_synode.h:64
#define REST_API_EXPORT
Definition: rest_api_export.h:15