Added basic REST interface to maxinfo plugin
This commit is contained in:
@ -415,13 +415,17 @@ resultset_stream_json(RESULTSET *set, DCB *dcb)
|
|||||||
{
|
{
|
||||||
RESULT_COLUMN *col;
|
RESULT_COLUMN *col;
|
||||||
RESULT_ROW *row;
|
RESULT_ROW *row;
|
||||||
|
int rowno = 0;
|
||||||
|
|
||||||
|
|
||||||
dcb_printf(dcb, "{ ");
|
dcb_printf(dcb, "[ ");
|
||||||
col = set->column;
|
|
||||||
while ((row = (*set->fetchrow)(set, set->userdata)) != NULL)
|
while ((row = (*set->fetchrow)(set, set->userdata)) != NULL)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
if (rowno++ > 0)
|
||||||
|
dcb_printf(dcb, ",\n");
|
||||||
|
dcb_printf(dcb, "{ ");
|
||||||
|
col = set->column;
|
||||||
while (col)
|
while (col)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -436,6 +440,7 @@ RESULT_ROW *row;
|
|||||||
dcb_printf(dcb, ", ");
|
dcb_printf(dcb, ", ");
|
||||||
}
|
}
|
||||||
resultset_free_row(row);
|
resultset_free_row(row);
|
||||||
|
dcb_printf(dcb, "}");
|
||||||
}
|
}
|
||||||
dcb_printf(dcb, "}\n");
|
dcb_printf(dcb, "]\n");
|
||||||
}
|
}
|
||||||
|
@ -127,5 +127,6 @@ extern void maxinfo_execute(DCB *, MAXINFO_TREE *);
|
|||||||
extern void maxinfo_send_error(DCB *, int, char *);
|
extern void maxinfo_send_error(DCB *, int, char *);
|
||||||
extern void maxinfo_send_parse_error(DCB *, char *, PARSE_ERROR);
|
extern void maxinfo_send_parse_error(DCB *, char *, PARSE_ERROR);
|
||||||
extern void maxinfo_send_error(DCB *, int, char *);
|
extern void maxinfo_send_error(DCB *, int, char *);
|
||||||
|
extern RESULTSET *maxinfo_variables();
|
||||||
|
extern RESULTSET *maxinfo_status();
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <gw.h>
|
#include <gw.h>
|
||||||
#include <modinfo.h>
|
#include <modinfo.h>
|
||||||
#include <log_manager.h>
|
#include <log_manager.h>
|
||||||
|
#include <resultset.h>
|
||||||
|
|
||||||
MODULE_INFO info = {
|
MODULE_INFO info = {
|
||||||
MODULE_API_PROTOCOL,
|
MODULE_API_PROTOCOL,
|
||||||
@ -129,10 +130,10 @@ GetModuleObject()
|
|||||||
static int
|
static int
|
||||||
httpd_read_event(DCB* dcb)
|
httpd_read_event(DCB* dcb)
|
||||||
{
|
{
|
||||||
//SESSION *session = dcb->session;
|
SESSION *session = dcb->session;
|
||||||
//ROUTER_OBJECT *router = session->service->router;
|
ROUTER_OBJECT *router = session->service->router;
|
||||||
//ROUTER *router_instance = session->service->router_instance;
|
ROUTER *router_instance = session->service->router_instance;
|
||||||
//void *rsession = session->router_session;
|
void *rsession = session->router_session;
|
||||||
|
|
||||||
int numchars = 1;
|
int numchars = 1;
|
||||||
char buf[HTTPD_REQUESTLINE_MAXLEN-1] = "";
|
char buf[HTTPD_REQUESTLINE_MAXLEN-1] = "";
|
||||||
@ -143,6 +144,7 @@ int cgi = 0;
|
|||||||
size_t i, j;
|
size_t i, j;
|
||||||
int headers_read = 0;
|
int headers_read = 0;
|
||||||
HTTPD_session *client_data = NULL;
|
HTTPD_session *client_data = NULL;
|
||||||
|
GWBUF *uri;
|
||||||
|
|
||||||
client_data = dcb->data;
|
client_data = dcb->data;
|
||||||
|
|
||||||
@ -234,13 +236,11 @@ HTTPD_session *client_data = NULL;
|
|||||||
/* send all the basic headers and close with \r\n */
|
/* send all the basic headers and close with \r\n */
|
||||||
httpd_send_headers(dcb, 1);
|
httpd_send_headers(dcb, 1);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* ToDO: launch proper content handling based on the requested URI, later REST interface
|
* 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 (strcmp(url, "/show") == 0) {
|
||||||
if (query_string && strlen(query_string)) {
|
if (query_string && strlen(query_string)) {
|
||||||
if (strcmp(query_string, "dcb") == 0)
|
if (strcmp(query_string, "dcb") == 0)
|
||||||
@ -249,6 +249,21 @@ HTTPD_session *client_data = NULL;
|
|||||||
dprintAllSessions(dcb);
|
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 */
|
/* force the client connecton close */
|
||||||
dcb_close(dcb);
|
dcb_close(dcb);
|
||||||
@ -345,6 +360,9 @@ int n_connect = 0;
|
|||||||
/* create the session data for HTTPD */
|
/* create the session data for HTTPD */
|
||||||
client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session));
|
client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session));
|
||||||
client->data = client_data;
|
client->data = client_data;
|
||||||
|
|
||||||
|
client->session =
|
||||||
|
session_alloc(dcb->session->service, client);
|
||||||
|
|
||||||
if (poll_add_dcb(client) == -1)
|
if (poll_add_dcb(client) == -1)
|
||||||
{
|
{
|
||||||
@ -354,7 +372,6 @@ int n_connect = 0;
|
|||||||
n_connect++;
|
n_connect++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(so);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n_connect;
|
return n_connect;
|
||||||
|
@ -34,10 +34,12 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <service.h>
|
#include <service.h>
|
||||||
#include <session.h>
|
#include <session.h>
|
||||||
|
#include <server.h>
|
||||||
#include <router.h>
|
#include <router.h>
|
||||||
#include <modules.h>
|
#include <modules.h>
|
||||||
#include <modinfo.h>
|
#include <modinfo.h>
|
||||||
#include <modutil.h>
|
#include <modutil.h>
|
||||||
|
#include <monitor.h>
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <spinlock.h>
|
#include <spinlock.h>
|
||||||
#include <dcb.h>
|
#include <dcb.h>
|
||||||
@ -47,6 +49,7 @@
|
|||||||
#include <log_manager.h>
|
#include <log_manager.h>
|
||||||
#include <resultset.h>
|
#include <resultset.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
#include <resultset.h>
|
||||||
|
|
||||||
|
|
||||||
MODULE_INFO info = {
|
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_statistics(INFO_INSTANCE *, INFO_SESSION *, GWBUF *);
|
||||||
static int maxinfo_ping(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 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 */
|
/* The router entry points */
|
||||||
@ -350,6 +354,10 @@ uint8_t *data;
|
|||||||
int length, len, residual;
|
int length, len, residual;
|
||||||
char *sql;
|
char *sql;
|
||||||
|
|
||||||
|
if (GWBUF_TYPE(queue) == GWBUF_TYPE_HTTP)
|
||||||
|
{
|
||||||
|
return handle_url(instance, session, queue);
|
||||||
|
}
|
||||||
if (session->queue)
|
if (session->queue)
|
||||||
{
|
{
|
||||||
queue = gwbuf_append(session->queue, queue);
|
queue = gwbuf_append(session->queue, queue);
|
||||||
@ -655,3 +663,48 @@ PARSE_ERROR err;
|
|||||||
maxinfo_execute(session->dcb, tree);
|
maxinfo_execute(session->dcb, tree);
|
||||||
return 1;
|
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;
|
||||||
|
}
|
||||||
|
@ -397,6 +397,29 @@ VARCONTEXT context;
|
|||||||
resultset_free(result);
|
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
|
* Variables that may be sent in a show variables
|
||||||
*/
|
*/
|
||||||
@ -486,6 +509,29 @@ VARCONTEXT context;
|
|||||||
resultset_free(result);
|
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
|
* Execute a select command parse tree and return the result set
|
||||||
|
Reference in New Issue
Block a user