From 8b1c0cd1a1f7d199b7db1a45ee9052eabeefb6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 17 Apr 2017 10:29:23 +0300 Subject: [PATCH] MXS-1220: Add REST resource handler class The Resource class is intended to be an abstraction of a resource tree. Each node in the tree can perform actions. The tree is traversed depth first so that deeper command paths resolve to the correct nodes. Currently all the base resources defined in the REST API documents are implemented in a way that they return a 200 OK response to all requests. When the internal data can be represented as JSON, the resources can be hooked up to functions that generate JSON. --- server/core/CMakeLists.txt | 1 + server/core/maxscale/resource.hh | 81 ++++++++++++++++++ server/core/resource.cc | 141 +++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 server/core/maxscale/resource.hh create mode 100644 server/core/resource.cc diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 1f43e66ce..fa0d3a4d6 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(maxscale-common SHARED queuemanager.cc random_jkiss.cc resultset.cc + resource.cc router.cc secrets.cc semaphore.cc diff --git a/server/core/maxscale/resource.hh b/server/core/maxscale/resource.hh new file mode 100644 index 000000000..d7fe6fd24 --- /dev/null +++ b/server/core/maxscale/resource.hh @@ -0,0 +1,81 @@ +#pragma once +/* + * Copyright (c) 2016 MariaDB Corporation Ab + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file and at www.mariadb.com/bsl11. + * + * Change Date: 2019-07-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2 or later of the General + * Public License. + */ + +/** @file REST API resources */ + +#include + +#include +#include +#include + +#include "http.hh" +#include "httprequest.hh" +#include "httpresponse.hh" + +using std::string; +using std::shared_ptr; +using std::map; + +class Resource; + +typedef shared_ptr SResource; +typedef map ResourceMap; + +class Resource +{ +public: + + Resource() { } + + virtual ~Resource() { } + + HttpResponse process_request(HttpRequest& request) + { + return process_request(request, 0); + } + +protected: + + /** + * @brief Handle a HTTP request + * + * This function should be overridden by the child classes. + * + * @param request Request to handle + * + * @return Response to the request + */ + virtual HttpResponse handle(HttpRequest& request) + { + ss_dassert(false); + return HttpResponse(HTTP_500_INTERNAL_SERVER_ERROR); + }; + + /** + * Internal functions + */ + HttpResponse process_request(HttpRequest& request, int depth); + + ResourceMap m_children; /**< Child resources */ +}; + +/** + * @brief Handle a HTTP request + * + * @param request Request to handle + * + * @return Response to request + */ +HttpResponse resource_handle_request(HttpRequest& request); diff --git a/server/core/resource.cc b/server/core/resource.cc new file mode 100644 index 000000000..2a195b9b6 --- /dev/null +++ b/server/core/resource.cc @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016 MariaDB Corporation Ab + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file and at www.mariadb.com/bsl11. + * + * Change Date: 2019-07-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2 or later of the General + * Public License. + */ + +#include + +#include "maxscale/resource.hh" +#include "maxscale/httprequest.hh" +#include "maxscale/httpresponse.hh" + +using mxs::SpinLock; +using mxs::SpinLockGuard; + +HttpResponse Resource::process_request(HttpRequest& request, int depth) +{ + ResourceMap::iterator it = m_children.find(request.uri_part(depth)); + + if (it != m_children.end()) + { + return it->second->process_request(request, depth + 1); + } + + return handle(request); +} + +class ServersResource: public Resource +{ +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +class ServicesResource: public Resource +{ +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +class FiltersResource: public Resource +{ +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +class MonitorsResource: public Resource +{ +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +class LogsResource : public Resource +{ +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +class SessionsResource: public Resource +{ +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +class UsersResource: public Resource +{ +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +class CoreResource: public Resource +{ +public: + CoreResource() + { + m_children["logs"] = SResource(new LogsResource()); + } + +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +class RootResource: public Resource +{ +public: + RootResource() + { + m_children["servers"] = SResource(new ServersResource()); + m_children["services"] = SResource(new ServicesResource()); + m_children["filters"] = SResource(new FiltersResource()); + m_children["monitors"] = SResource(new MonitorsResource()); + m_children["maxscale"] = SResource(new CoreResource()); + m_children["sessions"] = SResource(new SessionsResource()); + m_children["users"] = SResource(new UsersResource()); + } + +protected: + HttpResponse handle(HttpRequest& request) + { + return HttpResponse(HTTP_200_OK); + } +}; + +static RootResource resources; /**< Core resource set */ +static SpinLock resource_lock; + +HttpResponse resource_handle_request(HttpRequest& request) +{ + SpinLockGuard guard(resource_lock); + return resources.process_request(request); +}