MXS-1220: Add JSON formatting for servers and filters
Both the filters and services can be queried via the REST API now that these resources can be expressed in JSON format. As with the other resources, these directly call the functions that generate the data. This will be done via the inter-thread messaging system once it's in place.
This commit is contained in:
committed by
Markus Mäkelä
parent
9468893048
commit
b656f2b300
@ -467,7 +467,53 @@ filter_upstream(MXS_FILTER_DEF *filter, MXS_FILTER_SESSION *fsession, MXS_UPSTRE
|
||||
return me;
|
||||
}
|
||||
|
||||
json_t* filter_to_json(MXS_FILTER_DEF* filter)
|
||||
{
|
||||
json_t* rval = json_object();
|
||||
json_object_set_new(rval, "name", json_string(filter->name));
|
||||
json_object_set_new(rval, "module", json_string(filter->module));
|
||||
|
||||
if (filter->options)
|
||||
{
|
||||
json_t* arr = json_array();
|
||||
|
||||
for (int i = 0; filter->options && filter->options[i]; i++)
|
||||
{
|
||||
json_array_append_new(arr, json_string(filter->options[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(rval, "options", arr);
|
||||
}
|
||||
|
||||
if (filter->obj && filter->filter)
|
||||
{
|
||||
// TODO: Add filter diagnostics
|
||||
//filter->obj->diagnostics(filter->filter, NULL, dcb);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
json_t* filter_list_to_json()
|
||||
{
|
||||
json_t* rval = json_array();
|
||||
|
||||
spinlock_acquire(&filter_spin);
|
||||
|
||||
for (MXS_FILTER_DEF* f = allFilters; f; f = f->next)
|
||||
{
|
||||
json_t* json = filter_to_json(f);
|
||||
|
||||
if (json)
|
||||
{
|
||||
json_array_append_new(rval, json);
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_release(&filter_spin);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
namespace maxscale
|
||||
{
|
||||
|
||||
@ -76,10 +76,14 @@ class ServicesResource: public Resource
|
||||
protected:
|
||||
HttpResponse handle(HttpRequest& request)
|
||||
{
|
||||
int flags = request.get_option("pretty") == "true" ? JSON_INDENT(4) : 0;
|
||||
|
||||
if (request.uri_part_count() == 1)
|
||||
{
|
||||
// TODO: Generate this via the inter-thread messaging system
|
||||
Closer<json_t*> all_services(service_list_to_json());
|
||||
// Show all services
|
||||
return HttpResponse(HTTP_200_OK);
|
||||
return HttpResponse(HTTP_200_OK, mxs::json_dump(all_services, flags));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -87,8 +91,9 @@ protected:
|
||||
|
||||
if (service)
|
||||
{
|
||||
Closer<json_t*> service_js(service_to_json(service));
|
||||
// Show one service
|
||||
return HttpResponse(HTTP_200_OK);
|
||||
return HttpResponse(HTTP_200_OK, mxs::json_dump(service_js, flags));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -103,10 +108,13 @@ class FiltersResource: public Resource
|
||||
protected:
|
||||
HttpResponse handle(HttpRequest& request)
|
||||
{
|
||||
int flags = request.get_option("pretty") == "true" ? JSON_INDENT(4) : 0;
|
||||
|
||||
if (request.uri_part_count() == 1)
|
||||
{
|
||||
Closer<json_t*> filters(filter_list_to_json());
|
||||
// Show all filters
|
||||
return HttpResponse(HTTP_200_OK);
|
||||
return HttpResponse(HTTP_200_OK, mxs::json_dump(filters, flags));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -114,8 +122,9 @@ protected:
|
||||
|
||||
if (filter)
|
||||
{
|
||||
Closer<json_t*> filter_js(filter_to_json(filter));
|
||||
// Show one filter
|
||||
return HttpResponse(HTTP_200_OK);
|
||||
return HttpResponse(HTTP_200_OK, mxs::json_dump(filter_js, flags));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -38,7 +38,9 @@
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <maxscale/service.h>
|
||||
|
||||
#include <maxscale/cppdefs.hh>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -48,6 +50,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <math.h>
|
||||
#include <fcntl.h>
|
||||
#include <string>
|
||||
|
||||
#include <maxscale/service.h>
|
||||
#include <maxscale/alloc.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/paths.h>
|
||||
@ -65,6 +70,7 @@
|
||||
#include <maxscale/users.h>
|
||||
#include <maxscale/utils.h>
|
||||
#include <maxscale/version.h>
|
||||
#include <maxscale/jansson.h>
|
||||
|
||||
#include "maxscale/config.h"
|
||||
#include "maxscale/filter.h"
|
||||
@ -72,6 +78,8 @@
|
||||
#include "maxscale/queuemanager.h"
|
||||
#include "maxscale/service.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
/** Base value for server weights */
|
||||
#define SERVICE_BASE_SERVER_WEIGHT 1000
|
||||
|
||||
@ -2339,3 +2347,118 @@ bool service_port_is_used(unsigned short port)
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static const char* service_state_to_string(int state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case SERVICE_STATE_STARTED:
|
||||
return "Started";
|
||||
|
||||
case SERVICE_STATE_STOPPED:
|
||||
return "Stopped";
|
||||
|
||||
case SERVICE_STATE_FAILED:
|
||||
return "Failed";
|
||||
|
||||
case SERVICE_STATE_ALLOC:
|
||||
return "Allocated";
|
||||
|
||||
default:
|
||||
ss_dassert(false);
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
json_t* service_to_json(const SERVICE* service)
|
||||
{
|
||||
// TODO: Handle errors
|
||||
json_t* rval = json_object();
|
||||
|
||||
struct tm result;
|
||||
char timebuf[30];
|
||||
|
||||
json_object_set_new(rval, "name", json_string(service->name));
|
||||
json_object_set_new(rval, "router", json_string(service->routerModule));
|
||||
json_object_set_new(rval, "state", json_string(service_state_to_string(service->state)));
|
||||
|
||||
if (service->router && service->router_instance)
|
||||
{
|
||||
// TODO: Add router diagnostics
|
||||
//service->router->diagnostics(service->router_instance, dcb);
|
||||
}
|
||||
|
||||
asctime_r(localtime_r(&service->stats.started, &result), timebuf);
|
||||
json_object_set_new(rval, "started", json_string(timebuf));
|
||||
json_object_set_new(rval, "enable_root", json_boolean(service->enable_root));
|
||||
|
||||
if (service->n_filters)
|
||||
{
|
||||
json_t* arr = json_array();
|
||||
|
||||
for (int i = 0; i < service->n_filters; i++)
|
||||
{
|
||||
string filter = "/filters/";
|
||||
filter += service->filters[i]->name;
|
||||
json_array_append_new(arr, json_string(filter.c_str()));
|
||||
}
|
||||
|
||||
json_object_set_new(rval, "filters", arr);
|
||||
}
|
||||
|
||||
bool active_servers = false;
|
||||
|
||||
for (SERVER_REF* ref = service->dbref; ref; ref = ref->next)
|
||||
{
|
||||
if (SERVER_REF_IS_ACTIVE(ref))
|
||||
{
|
||||
active_servers = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (active_servers)
|
||||
{
|
||||
json_t* arr = json_array();
|
||||
|
||||
for (SERVER_REF* ref = service->dbref; ref; ref = ref->next)
|
||||
{
|
||||
string serv = "/servers/";
|
||||
serv += ref->server->unique_name;
|
||||
json_array_append_new(arr, json_string(serv.c_str()));
|
||||
}
|
||||
|
||||
json_object_set_new(rval, "servers", arr);
|
||||
}
|
||||
|
||||
if (service->weightby)
|
||||
{
|
||||
json_object_set_new(rval, "weightby", json_string(service->weightby));
|
||||
}
|
||||
|
||||
json_object_set_new(rval, "total_connections", json_integer(service->stats.n_sessions));
|
||||
json_object_set_new(rval, "connections", json_integer(service->stats.n_current));
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
json_t* service_list_to_json()
|
||||
{
|
||||
json_t* rval = json_array();
|
||||
|
||||
spinlock_acquire(&service_spin);
|
||||
|
||||
for (SERVICE *service = allServices; service && !rval; service = service->next)
|
||||
{
|
||||
json_t* svc = service_to_json(service);
|
||||
|
||||
if (svc)
|
||||
{
|
||||
json_array_append_new(rval, svc);
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_release(&service_spin);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user