Added basic REST interface to maxinfo plugin

This commit is contained in:
Mark Riddoch
2015-02-19 16:24:30 +00:00
parent 11e65f02f0
commit df3a548be1
5 changed files with 134 additions and 12 deletions

View File

@ -415,13 +415,17 @@ resultset_stream_json(RESULTSET *set, DCB *dcb)
{
RESULT_COLUMN *col;
RESULT_ROW *row;
int rowno = 0;
dcb_printf(dcb, "{ ");
col = set->column;
dcb_printf(dcb, "[ ");
while ((row = (*set->fetchrow)(set, set->userdata)) != NULL)
{
int i = 0;
if (rowno++ > 0)
dcb_printf(dcb, ",\n");
dcb_printf(dcb, "{ ");
col = set->column;
while (col)
{
@ -436,6 +440,7 @@ RESULT_ROW *row;
dcb_printf(dcb, ", ");
}
resultset_free_row(row);
dcb_printf(dcb, "}");
}
dcb_printf(dcb, "}\n");
dcb_printf(dcb, "]\n");
}

View File

@ -127,5 +127,6 @@ extern void maxinfo_execute(DCB *, MAXINFO_TREE *);
extern void maxinfo_send_error(DCB *, int, char *);
extern void maxinfo_send_parse_error(DCB *, char *, PARSE_ERROR);
extern void maxinfo_send_error(DCB *, int, char *);
extern RESULTSET *maxinfo_variables();
extern RESULTSET *maxinfo_status();
#endif

View File

@ -41,6 +41,7 @@
#include <gw.h>
#include <modinfo.h>
#include <log_manager.h>
#include <resultset.h>
MODULE_INFO info = {
MODULE_API_PROTOCOL,
@ -129,10 +130,10 @@ GetModuleObject()
static int
httpd_read_event(DCB* dcb)
{
//SESSION *session = dcb->session;
//ROUTER_OBJECT *router = session->service->router;
//ROUTER *router_instance = session->service->router_instance;
//void *rsession = session->router_session;
SESSION *session = dcb->session;
ROUTER_OBJECT *router = session->service->router;
ROUTER *router_instance = session->service->router_instance;
void *rsession = session->router_session;
int numchars = 1;
char buf[HTTPD_REQUESTLINE_MAXLEN-1] = "";
@ -143,6 +144,7 @@ int cgi = 0;
size_t i, j;
int headers_read = 0;
HTTPD_session *client_data = NULL;
GWBUF *uri;
client_data = dcb->data;
@ -234,13 +236,11 @@ HTTPD_session *client_data = NULL;
/* send all the basic headers and close with \r\n */
httpd_send_headers(dcb, 1);
#if 0
/**
* ToDO: launch proper content handling based on the requested URI, later REST interface
*
*/
dcb_printf(dcb, "Welcome to HTTPD MaxScale (c) %s\n\n", version_str);
if (strcmp(url, "/show") == 0) {
if (query_string && strlen(query_string)) {
if (strcmp(query_string, "dcb") == 0)
@ -249,6 +249,21 @@ HTTPD_session *client_data = NULL;
dprintAllSessions(dcb);
}
}
if (strcmp(url, "/services") == 0) {
RESULTSET *set, *seviceGetList();
if ((set = serviceGetList()) != NULL)
{
resultset_stream_json(set, dcb);
resultset_free(set);
}
}
#endif
if ((uri = gwbuf_alloc(strlen(url) + 1)) != NULL)
{
strcpy((char *)GWBUF_DATA(uri), url);
gwbuf_set_type(uri, GWBUF_TYPE_HTTP);
SESSION_ROUTE_QUERY(session, uri);
}
/* force the client connecton close */
dcb_close(dcb);
@ -345,6 +360,9 @@ int n_connect = 0;
/* create the session data for HTTPD */
client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session));
client->data = client_data;
client->session =
session_alloc(dcb->session->service, client);
if (poll_add_dcb(client) == -1)
{
@ -354,7 +372,6 @@ int n_connect = 0;
n_connect++;
}
}
close(so);
}
return n_connect;

View File

@ -34,10 +34,12 @@
#include <time.h>
#include <service.h>
#include <session.h>
#include <server.h>
#include <router.h>
#include <modules.h>
#include <modinfo.h>
#include <modutil.h>
#include <monitor.h>
#include <atomic.h>
#include <spinlock.h>
#include <dcb.h>
@ -47,6 +49,7 @@
#include <log_manager.h>
#include <resultset.h>
#include <version.h>
#include <resultset.h>
MODULE_INFO info = {
@ -66,6 +69,7 @@ static char *version_str = "V1.0.0";
static int maxinfo_statistics(INFO_INSTANCE *, INFO_SESSION *, GWBUF *);
static int maxinfo_ping(INFO_INSTANCE *, INFO_SESSION *, GWBUF *);
static int maxinfo_execute_query(INFO_INSTANCE *, INFO_SESSION *, char *);
static int handle_url(INFO_INSTANCE *instance, INFO_SESSION *router_session, GWBUF *queue);
/* The router entry points */
@ -350,6 +354,10 @@ uint8_t *data;
int length, len, residual;
char *sql;
if (GWBUF_TYPE(queue) == GWBUF_TYPE_HTTP)
{
return handle_url(instance, session, queue);
}
if (session->queue)
{
queue = gwbuf_append(session->queue, queue);
@ -655,3 +663,48 @@ PARSE_ERROR err;
maxinfo_execute(session->dcb, tree);
return 1;
}
typedef RESULTSET *(*RESULTSETFUNC)();
static struct {
char *uri;
RESULTSETFUNC func
} supported_uri[] = {
{ "/services", serviceGetList },
{ "/listeners", serviceGetListenerList },
{ "/modules", moduleGetList },
{ "/monitors", monitorGetList },
{ "/sessions", sessionGetList },
{ "/servers", serverGetList },
{ "/variables", maxinfo_variables },
{ "/status", maxinfo_status },
{ NULL, NULL }
};
/**
* We have data from the client, this is a HTTP URL
*
* @param instance The router instance
* @param session The router session returned from the newSession call
* @param queue The queue of data buffers to route
* @return The number of bytes sent
*/
static int
handle_url(INFO_INSTANCE *instance, INFO_SESSION *session, GWBUF *queue)
{
char *uri;
int i;
RESULTSET *set;
uri = (char *)GWBUF_DATA(queue);
for (i = 0; supported_uri[i].uri; i++)
{
if (strcmp(uri, supported_uri[i].uri) == 0)
{
set = (*supported_uri[i].func)();
resultset_stream_json(set, session->dcb);
resultset_free(set);
}
}
return 1;
}

View File

@ -397,6 +397,29 @@ VARCONTEXT context;
resultset_free(result);
}
/**
* Return the show variables output a a result set
*
* @return Variables as a result set
*/
RESULTSET *
maxinfo_variables()
{
RESULTSET *result;
static VARCONTEXT context;
context.like = NULL;
context.index = 0;
if ((result = resultset_create(variable_row, &context)) == NULL)
{
return NULL;
}
resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR);
resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR);
return result;
}
/**
* Variables that may be sent in a show variables
*/
@ -486,6 +509,29 @@ VARCONTEXT context;
resultset_free(result);
}
/**
* Return the show status data as a result set
*
* @return The show status data as a result set
*/
RESULTSET *
maxinfo_status()
{
RESULTSET *result;
static VARCONTEXT context;
context.like = NULL;
context.index = 0;
if ((result = resultset_create(status_row, &context)) == NULL)
{
return NULL;
}
resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR);
resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR);
return result;
}
/**
* Execute a select command parse tree and return the result set