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:
parent
9468893048
commit
b656f2b300
@ -246,6 +246,22 @@ const char* filter_def_get_module_name(const MXS_FILTER_DEF* filter_def);
|
||||
*/
|
||||
MXS_FILTER* filter_def_get_instance(const MXS_FILTER_DEF* filter_def);
|
||||
|
||||
/**
|
||||
* @brief Convert a filter to JSON
|
||||
*
|
||||
* @param filter Filter to convert
|
||||
*
|
||||
* @return Filter converted to JSON format
|
||||
*/
|
||||
json_t* filter_to_json(MXS_FILTER_DEF* filter);
|
||||
|
||||
/**
|
||||
* @brief Convert all filters into JSON
|
||||
*
|
||||
* @return A JSON array containing all filters
|
||||
*/
|
||||
json_t* filter_list_to_json();
|
||||
|
||||
void dprintAllFilters(DCB *);
|
||||
void dprintFilter(DCB *, const MXS_FILTER_DEF *);
|
||||
void dListFilters(DCB *);
|
||||
|
@ -19,7 +19,13 @@
|
||||
*/
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include <maxscale/protocol.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/dcb.h>
|
||||
@ -30,10 +36,7 @@
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/config.h>
|
||||
#include <maxscale/queuemanager.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <maxscale/jansson.h>
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
@ -276,6 +279,22 @@ int service_refresh_users(SERVICE *service);
|
||||
*/
|
||||
void service_print_users(DCB *, const SERVICE *);
|
||||
|
||||
/**
|
||||
* @brief Convert a service to JSON
|
||||
*
|
||||
* @param service Service to convert
|
||||
*
|
||||
* @return JSON representation of the service
|
||||
*/
|
||||
json_t* service_to_json(const SERVICE* service);
|
||||
|
||||
/**
|
||||
* @brief Convert all services to JSON
|
||||
*
|
||||
* @return A JSON array with all services
|
||||
*/
|
||||
json_t* service_list_to_json();
|
||||
|
||||
void dprintAllServices(DCB *dcb);
|
||||
void dprintService(DCB *dcb, SERVICE *service);
|
||||
void dListServices(DCB *dcb);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user