From 1c869e49a7a2f69f9d32e76917a1c78b1dc1dc66 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 2 Apr 2017 12:56:46 +0200 Subject: [PATCH] api: use new request / response format --- doc/RemoteAPI.md | 45 +++++++++++++++++++++++-------- lib/api.c | 48 ++++++++++++++++++++++----------- lib/apis/config.c | 11 +------- tests/integration/api-config.sh | 20 +++++++++----- 4 files changed, 80 insertions(+), 44 deletions(-) diff --git a/doc/RemoteAPI.md b/doc/RemoteAPI.md index 4f6fbadaa..59fbd80d5 100644 --- a/doc/RemoteAPI.md +++ b/doc/RemoteAPI.md @@ -28,24 +28,25 @@ _This transport is not implemented yet_ ## Commands -### `reload` +### `restart` Restart VILLASnode with a new configuration file. **Request:** _application/json_ { - "request": "reload", - "id": "edei4shahNgucoo7paeth8chue0iyook" - "configuration": "smb://MY-WINDOWS-HOST/SHARE1/path/to/config.conf" + "request": "restart", + "id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a" + "args" : { + "configuration": "smb://MY-WINDOWS-HOST/SHARE1/path/to/config.conf" + } } **Response:** _application/json_ { "response": "reload", - "id": "edei4shahNgucoo7paeth8chue0iyook", - "status": "success" + "id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a" } ### `config` @@ -56,16 +57,15 @@ Retrieve the contents of the current configuration. { "request": "config", - "id": "oom3lie7nee4Iepieng8ae4ueToebeki" - "configuration": "smb://MY-WINDOWS-HOST/SHARE1/path/to/config.conf" + "id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a" } **Response:** _application/json_ { "response": "config", - "id": "oom3lie7nee4Iepieng8ae4ueToebeki", - "config" : { + "id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a", + "response" : { "nodes" : { "socket_node" : { "type": "socket", @@ -86,7 +86,30 @@ Retrieve the contents of the current configuration. Get a list of currently active nodes. -_This request is not implemented yet_ +**Request:** _application/json_ + + { + "request": "nodes", + "id": "5a786626-fbc6-4c04-98c2-48027e68c2fa" + } + +**Response:** _application/json_ + + { + "command": "nodes", + "response": [ + { + "name": "ws", + "state": 4, + "vectorize": 1, + "affinity": 0, + "id": 0, + "type": "websocket", + "description": "Demo Channel" + } + ], + "id": "5a786626-fbc6-4c04-98c2-48027e68c2fa" + } ### `paths` diff --git a/lib/api.c b/lib/api.c index 3adb272b7..c63bfb5fe 100644 --- a/lib/api.c +++ b/lib/api.c @@ -72,39 +72,55 @@ retry: len = json_dumpb(res, b->buf + b->len, b->size - b->len, 0); return 0; } -int api_session_run_command(struct api_session *s, json_t *req, json_t **resp) +int api_session_run_command(struct api_session *s, json_t *json_in, json_t **json_out) { int ret; const char *rstr; + char *id; struct plugin *p; - json_t *args; + json_t *json_args = NULL, *json_resp; - ret = json_unpack(req, "{ s: s, s: o }", - "command", &rstr, - "arguments", &args); - if (ret) - *resp = json_pack("{ s: s, s: d }", + ret = json_unpack(json_in, "{ s: s, s: s, s?: o }", + "request", &rstr, + "id", &id, + "args", &json_args); + if (ret) { + *json_out = json_pack("{ s: s, s: s, s: i, s: s }", + "command", rstr, "error", "invalid request", - "code", -1); + "code", -1, + "id", id); + goto out; + } p = plugin_lookup(PLUGIN_TYPE_API, rstr); - if (!p) - *resp = json_pack("{ s: s, s: d, s: s }", + if (!p) { + *json_out = json_pack("{ s: s, s: s, s: d, s: s, s: s }", + "command", rstr, "error", "command not found", "code", -2, - "command", rstr); - + "command", rstr, + "id", id); + goto out; + } debug(LOG_API, "Running API request: %s", p->name); - ret = p->api.cb(&p->api, args, resp, s); + ret = p->api.cb(&p->api, json_args, &json_resp, s); if (ret) - *resp = json_pack("{ s: s, s: d }", + *json_out = json_pack("{ s: s, s: s, s: s }", + "command", rstr, "error", "command failed", - "code", ret); + "code", ret, + "id", id); + else + *json_out = json_pack("{ s: s, s: o, s: s }", + "command", rstr, + "response", json_resp, + "id", id); - debug(LOG_API, "API request completed with code: %d", ret); +out: debug(LOG_API, "API request completed with code: %d", ret); return 0; } diff --git a/lib/apis/config.c b/lib/apis/config.c index 4c054e28b..ae41e6e53 100644 --- a/lib/apis/config.c +++ b/lib/apis/config.c @@ -16,16 +16,7 @@ static int api_config(struct api_ressource *h, json_t *args, json_t **resp, stru { config_setting_t *cfg_root = config_root_setting(&s->api->super_node->cfg); - if (cfg_root) { - *resp = json_pack("{ s: o }", - "config", config_to_json(cfg_root)); - } - /* No configuration has been loaded yet. */ - else { - *resp = json_pack("{ s: s, s: i }", - "error", "no configuration loaded", - "code", 2); - } + *resp = cfg_root ? config_to_json(cfg_root) : json_object(); return 0; } diff --git a/tests/integration/api-config.sh b/tests/integration/api-config.sh index 72fd5d0dd..f18ed1e97 100755 --- a/tests/integration/api-config.sh +++ b/tests/integration/api-config.sh @@ -1,26 +1,32 @@ #!/bin/bash -LOCAL_CONF=${SRCDIR}/etc/loopback.conf -FETCHED_CONF=$(mktemp) +set -e -echo ${CONF} +LOCAL_CONF=${SRCDIR}/etc/loopback.conf + +FETCHED_CONF=$(mktemp) +FETCHED_JSON_CONF=$(mktemp) +LOCAL_JSON_CONF=$(mktemp) # Start VILLASnode instance with local config (via advio) villas-node file://${LOCAL_CONF} & +# Wait for node to complete init sleep 1 # Fetch config via API -curl -sX POST --data '{ "command" : "config" }' http://localhost/api/v1 2>/dev/null > ${FETCHED_CONF} +curl -sX POST --data '{ "request" : "config", "id" : "5a786626-fbc6-4c04-98c2-48027e68c2fa" }' http://localhost/api/v1 > ${FETCHED_CONF} # Shutdown VILLASnode kill $! -# Compare local config with the fetched one -diff -u <(cat ${LOCAL_CONF} | conf2json | jq -S .) <(cat ${FETCHED_CONF} | jq -S .config) +conf2json < ${LOCAL_CONF} | jq -S . > ${LOCAL_JSON_CONF} +jq -S .response < ${FETCHED_CONF} > ${FETCHED_JSON_CONF} +# Compare local config with the fetched one +diff -u ${FETCHED_JSON_CONF} ${LOCAL_JSON_CONF} RC=$? -rm -f ${FETCHED_CONF} +rm -f ${FETCHED_CONF} ${FETCHED_JSON_CONF} ${LOCAL_JSON_CONF} exit $RC \ No newline at end of file