From: Sebastian Harl Date: Tue, 30 Sep 2014 12:40:53 +0000 (-0700) Subject: frontend: Added support for LISTing services and metrics as well. X-Git-Tag: sysdb-0.5.0~26 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=4bc282b73a0d1d526e38c4220be46de17bbf4932 frontend: Added support for LISTing services and metrics as well. When listing objects other than hosts, the returned JSON list will include the respective type listed below each host object. --- diff --git a/src/frontend/connection-private.h b/src/frontend/connection-private.h index a874751..dd4bcce 100644 --- a/src/frontend/connection-private.h +++ b/src/frontend/connection-private.h @@ -89,6 +89,7 @@ typedef struct { typedef struct { sdb_conn_node_t super; + int type; conn_matcher_t *filter; } conn_list_t; #define CONN_LIST(obj) ((conn_list_t *)(obj)) diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index 58363df..289d357 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -262,6 +262,7 @@ list_statement: $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_list_t, conn_list_destroy)); + CONN_LIST($$)->type = SDB_HOST; CONN_LIST($$)->filter = CONN_MATCHER($3); $$->cmd = CONNECTION_LIST; free($2); $2 = NULL; diff --git a/src/frontend/query.c b/src/frontend/query.c index f55975e..0ee734c 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -31,6 +31,7 @@ #include "frontend/connection-private.h" #include "frontend/parser.h" #include "utils/error.h" +#include "utils/proto.h" #include "utils/strbuf.h" #include @@ -135,9 +136,21 @@ sdb_fe_fetch(sdb_conn_t *conn) int sdb_fe_list(sdb_conn_t *conn) { + int type = SDB_HOST; + if ((! conn) || (conn->cmd != CONNECTION_LIST)) return -1; - return sdb_fe_exec_list(conn, /* filter = */ NULL); + + if (conn->cmd_len == sizeof(uint32_t)) + type = sdb_proto_get_int(conn->buf, 0); + else if (conn->cmd_len) { + sdb_log(SDB_LOG_ERR, "frontend: Invalid command length %d for " + "LIST command", conn->cmd_len); + sdb_strbuf_sprintf(conn->errbuf, "LIST: Invalid command length %d", + conn->cmd_len); + return -1; + } + return sdb_fe_exec_list(conn, type, /* filter = */ NULL); } /* sdb_fe_list */ int @@ -181,7 +194,7 @@ sdb_fe_exec(sdb_conn_t *conn, sdb_conn_node_t *node) case CONNECTION_LIST: if (CONN_LIST(node)->filter) filter = CONN_LIST(node)->filter->matcher; - return sdb_fe_exec_list(conn, filter); + return sdb_fe_exec_list(conn, CONN_LIST(node)->type, filter); case CONNECTION_LOOKUP: if (CONN_LOOKUP(node)->matcher) m = CONN_LOOKUP(node)->matcher->matcher; @@ -206,7 +219,7 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, const char *name, { sdb_strbuf_t *buf; sdb_store_obj_t *host; - uint32_t type = htonl(CONNECTION_FETCH); + uint32_t res_type = htonl(CONNECTION_FETCH); host = sdb_store_get_host(name); if (! host) { @@ -230,7 +243,7 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, const char *name, return -1; } - sdb_strbuf_memcpy(buf, &type, sizeof(uint32_t)); + sdb_strbuf_memcpy(buf, &res_type, sizeof(uint32_t)); if (sdb_store_host_tojson(host, buf, filter, /* flags = */ 0)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to serialize " "host '%s' to JSON", name); @@ -248,10 +261,26 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, const char *name, } /* sdb_fe_exec_fetch */ int -sdb_fe_exec_list(sdb_conn_t *conn, sdb_store_matcher_t *filter) +sdb_fe_exec_list(sdb_conn_t *conn, int type, sdb_store_matcher_t *filter) { sdb_strbuf_t *buf; - uint32_t type = htonl(CONNECTION_LIST); + uint32_t res_type = htonl(CONNECTION_LIST); + + int flags; + + if (type == SDB_HOST) + flags = SDB_SKIP_ALL; + else if (type == SDB_SERVICE) + flags = SDB_SKIP_ALL & (~SDB_SKIP_SERVICES); + else if (type == SDB_METRIC) + flags = SDB_SKIP_ALL & (~SDB_SKIP_METRICS); + else { + sdb_log(SDB_LOG_ERR, "frontend: Invalid object type %d " + "for LIST command", type); + sdb_strbuf_sprintf(conn->errbuf, + "LIST: Invalid object type %d", type); + return -1; + } buf = sdb_strbuf_create(1024); if (! buf) { @@ -265,8 +294,8 @@ sdb_fe_exec_list(sdb_conn_t *conn, sdb_store_matcher_t *filter) return -1; } - sdb_strbuf_memcpy(buf, &type, sizeof(uint32_t)); - if (sdb_store_tojson(buf, filter, /* flags = */ SDB_SKIP_ALL)) { + sdb_strbuf_memcpy(buf, &res_type, sizeof(uint32_t)); + if (sdb_store_tojson(buf, filter, flags)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to serialize " "store to JSON"); sdb_strbuf_sprintf(conn->errbuf, "Out of memory"); @@ -285,7 +314,7 @@ sdb_fe_exec_lookup(sdb_conn_t *conn, sdb_store_matcher_t *m, sdb_store_matcher_t *filter) { tojson_data_t data = { NULL, filter, 0 }; - uint32_t type = htonl(CONNECTION_LOOKUP); + uint32_t res_type = htonl(CONNECTION_LOOKUP); data.buf = sdb_strbuf_create(1024); if (! data.buf) { @@ -299,7 +328,7 @@ sdb_fe_exec_lookup(sdb_conn_t *conn, sdb_store_matcher_t *m, return -1; } - sdb_strbuf_memcpy(data.buf, &type, sizeof(uint32_t)); + sdb_strbuf_memcpy(data.buf, &res_type, sizeof(uint32_t)); sdb_strbuf_append(data.buf, "["); /* Let the JSON serializer handle the filter instead of the scanner. Else, @@ -327,7 +356,7 @@ sdb_fe_exec_timeseries(sdb_conn_t *conn, sdb_timeseries_opts_t *opts) { sdb_strbuf_t *buf; - uint32_t type = htonl(CONNECTION_TIMESERIES); + uint32_t res_type = htonl(CONNECTION_TIMESERIES); buf = sdb_strbuf_create(1024); if (! buf) { @@ -340,7 +369,7 @@ sdb_fe_exec_timeseries(sdb_conn_t *conn, return -1; } - sdb_strbuf_memcpy(buf, &type, sizeof(uint32_t)); + sdb_strbuf_memcpy(buf, &res_type, sizeof(uint32_t)); if (sdb_store_fetch_timeseries(hostname, metric, opts, buf)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to fetch time-series"); sdb_strbuf_sprintf(conn->errbuf, "Failed to fetch time-series"); diff --git a/src/include/frontend/connection.h b/src/include/frontend/connection.h index e963c94..8189470 100644 --- a/src/include/frontend/connection.h +++ b/src/include/frontend/connection.h @@ -201,15 +201,16 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, const char *name, /* * sdb_fe_exec_list: * Execute the 'LIST' command. Send a complete listing of the store, - * serialized as JSON, to the client. If specified, only objects matching the - * filter will be included. See sdb_store_tojson for details. + * serialized as JSON, to the client. The listing includes all hosts and the + * specified object type. If specified, only objects matching the filter will + * be included. See sdb_store_tojson for details. * * Returns: * - 0 on success * - a negative value else */ int -sdb_fe_exec_list(sdb_conn_t *conn, sdb_store_matcher_t *filter); +sdb_fe_exec_list(sdb_conn_t *conn, int type, sdb_store_matcher_t *filter); /* * sdb_fe_exec_lookup: diff --git a/src/include/frontend/proto.h b/src/include/frontend/proto.h index 91dd360..de45f73 100644 --- a/src/include/frontend/proto.h +++ b/src/include/frontend/proto.h @@ -177,7 +177,9 @@ typedef enum { /* * CONNECTION_LIST: - * Execute the 'LIST' command in the server. + * Execute the 'LIST' command in the server. The message body may include + * the type of the objects to be included in addition to all hosts, + * encoded as a 32bit integer in network byte-order. */ CONNECTION_LIST,