From 0631be19cb7a8334f0e159fbe6bd1be9286f6595 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 18 Sep 2018 22:49:29 +0200 Subject: [PATCH] * Notification event streams enhancements * Yang 1.1 notification support * Event stream discovery support according to RFC 5277 Sec 3.2.5.1 (netconf) and RFC 8040 (restconf) --- CHANGELOG.md | 3 + apps/backend/backend_client.c | 107 +++++++++++-- apps/backend/backend_main.c | 10 +- apps/backend/clixon_backend_handle.c | 2 + apps/cli/cli_handle.c | 12 +- apps/restconf/README.md | 4 +- lib/clixon/clixon.h.in | 1 + lib/clixon/clixon_handle.h | 5 + lib/clixon/clixon_yang.h | 1 + lib/src/Makefile.in | 2 +- lib/src/clixon_handle.c | 33 +++- lib/src/clixon_yang.c | 52 +++++- lib/src/clixon_yang_parse.y | 37 ++++- test/test_event.sh | 117 ++++++++++++++ yang/Makefile.in | 1 + yang/ietf-restconf-monitoring@2017-01-26.yang | 149 ++++++++++++++++++ 16 files changed, 502 insertions(+), 34 deletions(-) create mode 100755 test/test_event.sh create mode 100644 yang/ietf-restconf-monitoring@2017-01-26.yang diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f780790..0a46eab7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ ### Major New features ### API changes on existing features (you may need to change your code) +* Notification event streams enhancements + * Yang 1.1 notification support + * Event stream discovery support according to RFC 5277 Sec 3.2.5.1 (netconf) and RFC 8040 (restconf) * clixon_restconf and clixon_netconf now take -D as command-line option instead of just -D * This aligns to clixon_cli and clixon_backend * Application command option -S to clixon_netconf is obsolete. Use `clixon_netconf -l s` instead. diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 224b371d..71714e68 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -99,20 +99,10 @@ client_subscription_add(struct client_entry *ce, return su; } -static struct client_entry * -ce_find_bypid(struct client_entry *ce_list, int pid) -{ - struct client_entry *ce; - - for (ce = ce_list; ce; ce = ce->ce_next) - if (ce->ce_pid == pid) - return ce; - return NULL; -} - +/*! Delete stream subscription from client subscription list */ static int client_subscription_delete(struct client_entry *ce, - struct client_subscription *su0) + struct client_subscription *su0) { struct client_subscription *su; struct client_subscription **su_prev; @@ -134,7 +124,8 @@ client_subscription_delete(struct client_entry *ce, #ifdef notused /* xxx */ static struct client_subscription * -client_subscription_find(struct client_entry *ce, char *stream) +client_subscription_find(struct client_entry *ce, + char *stream) { struct client_subscription *su = NULL; @@ -146,6 +137,18 @@ client_subscription_find(struct client_entry *ce, char *stream) } #endif +static struct client_entry * +ce_find_bypid(struct client_entry *ce_list, + int pid) +{ + struct client_entry *ce; + + for (ce = ce_list; ce; ce = ce->ce_next) + if (ce->ce_pid == pid) + return ce; + return NULL; +} + /*! Remove client entry state * Close down everything wrt clients (eg sockets, subscriptions) * Finally actually remove client struct in handle @@ -258,6 +261,79 @@ from_client_get_config(clicon_handle h, return retval; } +static int +client_get_streams(clicon_handle h, + char *xpath, + cxobj **xtop) +{ + int retval = -1; + cxobj *x = NULL; + cxobj *xc; + char *reason = NULL; + yang_spec *yspec; + cbuf *cb; + + if ((yspec = clicon_dbspec_yang(h)) == NULL){ + clicon_err(OE_YANG, ENOENT, "No yang spec"); + goto done; + } + if (*xtop==NULL){ + clicon_err(OE_CFG, ENOENT, "XML tree expected"); + goto done; + } + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, 0, "clicon buffer"); + goto done; + } + cprintf(cb,""); + if (stream_get_xml(h, cb) < 0) + goto done; + cprintf(cb,""); + /* XXX. yspec */ + if (xml_parse_string(cbuf_get(cb), NULL, &x) < 0) + goto done; + if (xml_merge(*xtop, x, yspec, &reason) < 0) + goto done; + if (reason){ + while ((xc = xml_child_i(*xtop, 0)) != NULL) + xml_purge(xc); + if (netconf_operation_failed_xml(xtop, "rpc", reason)< 0) + goto done; + goto ok; + } +#ifdef notyet + /* Code complex to filter out anything that is outside of xpath */ + if (xpath_vec(*xtop, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + goto done; + + /* If vectors are specified then mark the nodes found and + * then filter out everything else, + * otherwise return complete tree. + */ + if (xvec != NULL){ + for (i=0; i