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.
This commit is contained in:
Markus Mäkelä 2017-04-17 10:29:23 +03:00 committed by Markus Mäkelä
parent e248178349
commit 8b1c0cd1a1
3 changed files with 223 additions and 0 deletions

View File

@ -34,6 +34,7 @@ add_library(maxscale-common SHARED
queuemanager.cc
random_jkiss.cc
resultset.cc
resource.cc
router.cc
secrets.cc
semaphore.cc

View File

@ -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 <maxscale/cppdefs.hh>
#include <string>
#include <map>
#include <tr1/memory>
#include "http.hh"
#include "httprequest.hh"
#include "httpresponse.hh"
using std::string;
using std::shared_ptr;
using std::map;
class Resource;
typedef shared_ptr<Resource> SResource;
typedef map<string, SResource> 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);

141
server/core/resource.cc Normal file
View File

@ -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 <maxscale/spinlock.hh>
#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);
}