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