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