diff --git a/CHANGELOG.md b/CHANGELOG.md index deaa7942..375bdb39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,8 @@ Users may have to change how they access the system * Restconf native HTTP/2: * Added option `CLICON_RESTCONF_HTTP2_PLAIN` for non-TLS http * Default disabled, set to true to enable HTTP/2 direct and switch/upgrade HTTP/1->HTTP/2 +* JSON encoding of YANG metadata according to RFC 7952 + * XML -> JSON translation * Restconf internal start: fail early if clixon_restconf binary is not found * If CLICON_BACKEND_RESTCONF_PROCESS is true * Added linenumbers to all YANG symbols for better debug and errors @@ -1416,7 +1418,7 @@ Olof Hagsand * Clixon used to play the (already made) commit callbacks in reverse order * Many validation functions have changed error parameter from cbuf to xml tree. * XML trees are more flexible for utility tools - * If you use these(mostly internal), you need to change the error function: `generic_validate, from_validate_common, xml_yang_validate_all_top, xml_yang_validate_all, xml_yang_validate_add, xml_yang_validate_rpc, xml_yang_validate_list_key_only` + * If you use these(mostly internal), you need to change the error function: `generic_validate, from_validate_common, xml_yang_validate_all_top, xml_yang_validate_all, xml_yang_validate_add, xml_yang_validate_pprpc, xml_yang_validate_list_key_only` * Datastore cache and xmldb_get() changes: * You need to remove `msd` (last) parameter of `xmldb_get()`: * `xmldb_get(h, "running", "/", &xt, NULL)` --> `xmldb_get(h, "running", "/", &xt)` diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index d546b4c4..445cf5f0 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -1662,10 +1662,10 @@ from_client_get_pageable_list(clicon_handle h, cprintf(cb, "%u", remaining); if (xml_value_set(xa, cbuf_get(cb)) < 0) goto done; - if (xml_prefix_set(xa, "lpg") < 0) - goto done; - if (xmlns_set(x, "ycoll", "urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination") < 0) - goto done; + if (xml_prefix_set(xa, "ycoll") < 0) + goto done; + if (xmlns_set(x, "ycoll", "urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination") < 0) + goto done; } /* Top level is data, so add 1 to depth if significant */ if (clicon_xml2cbuf(cbret, x, 0, 0, depth>0?depth+1:depth) < 0) diff --git a/lib/clixon/clixon_yang_module.h b/lib/clixon/clixon_yang_module.h index d1431f4b..0a6cfd62 100644 --- a/lib/clixon/clixon_yang_module.h +++ b/lib/clixon/clixon_yang_module.h @@ -76,6 +76,7 @@ yang_stmt *yang_find_module_by_namespace(yang_stmt *yspec, char *ns); yang_stmt *yang_find_module_by_namespace_revision(yang_stmt *yspec, const char *ns, const char *revision); yang_stmt *yang_find_module_by_name_revision(yang_stmt *yspec, const char *name, const char *revision); yang_stmt *yang_find_module_by_name(yang_stmt *yspec, char *name); +int yang_metadata_annotation_check(cxobj *x, yang_stmt *ymod, int *ismeta); int yang_metadata_init(clicon_handle h); #endif /* _CLIXON_YANG_MODULE_H_ */ diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c index 650bc327..8181a5a8 100644 --- a/lib/src/clixon_json.c +++ b/lib/src/clixon_json.c @@ -688,6 +688,39 @@ nullchild(cbuf *cb, return retval; } +/*! +{ + "example-social:uint8-numbers": [17], + "@example-social:uint8-numbers": [ + { + "ietf-list-pagination:remaining": 5 + } + ] + } + */ +static int +json_metadata_encoding(cbuf *cb, + cxobj *x, + int level, + int pretty, + char *modname, + char *name, + char *modname2, + char *name2, + char *val) +{ + int retval = -1; + + cprintf(cb, ",\"@%s:%s\": [", modname, name); + cprintf(cb, "%*s", pretty?((level+1)*JSON_INDENT):0, "{"); + cprintf(cb, "\"%s:%s\": %s", modname2, name2, val); + cprintf(cb, "%*s", pretty?((level+1)*JSON_INDENT):0, "}"); + cprintf(cb, "%*s", pretty?(level*JSON_INDENT):0, "]"); + retval = 0; + // done: + return retval; +} + /*! Do the actual work of translating XML to JSON * @param[out] cb Cligen text buffer containing json on exit * @param[in] x XML tree structure containing XML to translate @@ -840,13 +873,8 @@ xml2json1_cbuf(cbuf *cb, commas = xml_child_nr_notype(x, CX_ATTR) - 1; for (i=0; i $fstate EOF +# Run limitonly test with netconf, restconf+xml and restconf+json +# Args: +# 1. limit +# 2. remaining +# 3. list XXX remaining +function testlimit() +{ + limit=$1 + remaining=$2 + + new "limit=$limit NETCONF" + expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLOds:running/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers$limit]]>]]>" "17]]>]]>$" + + new "limit=$limit Parameter RESTCONF xml" + expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-collection+xml" $RCPROTO://localhost/restconf/data/example-social:members/member=alice/favorites/uint8-numbers?limit=$limit)" 0 "HTTP/$HVER 200" "Content-Type: application/yang-collection+xml" "17" + + # XXX [17] + new "limit=$limit Parameter RESTCONF json" + expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-collection+json" $RCPROTO://localhost/restconf/data/example-social:members/member=alice/favorites/uint8-numbers?limit=$limit)" 0 "HTTP/$HVER 200" "Content-Type: application/yang-collection+json" "{\"pageable-list\":{\"example-social:uint8-numbers\":17,\"@example-social:uint8-numbers\": \[{\"ietf-netconf-list-pagination:remaining\": $remaining}\]}}" +} + new "test params: -f $cfg -s startup -- -sS $fstate" if [ $BE -ne 0 ]; then @@ -284,22 +306,11 @@ fi new "wait restconf" wait_restconf -new "A.3.1.1. 'limit=1' NETCONF" -# XXX: augment GET instead, not RPC -#expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLOds:running/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers1]]>]]>" "17]]>]]>$" +new "A.3.1.1. limit=1" +testlimit 1 5 "[17]" -new "A.3.1.1. 'limit' Parameter RESTCONF xml" -#expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-collection+xml" $RCPROTO://localhost/restconf/data/example-social:members/member=alice/favorites/uint8-numbers?limit=1)" 0 "HTTP/$HVER 200" "Content-Type: application/yang-collection+xml" "17" - -new "A.3.1.1. 'limit' Parameter RESTCONF json" -expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-collection+json" $RCPROTO://localhost/restconf/data/example-social:members/member=alice/favorites/uint8-numbers?limit=1)" 0 "HTTP/$HVER 200" "Content-Type: application/yang-collection+json" {'"pageable-list":{"example-social:uint8-numbers":17}}' -exit - -#new "A.3.1.1. 'limit' Parameter RESTCONF" -#expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-collection+xml" $RCPROTO://localhost/restconf/data/ietf-netconf-list-pagination:get-pageable-list -d "ds:running/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers1")" 0 "HTTP/$HVER 200" "Content-Type: application/yang-collection+xml" foo -exit -new "A.3.1.2. 'limit=2' NETCONF" -expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLOds:running/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers2]]>]]>" "1713]]>]]>$" +#new "A.3.1.2. limit=2" +#testlimit 2 4 "[17 13]" # CLI # XXX This relies on a very specific clispec command: need a more generic test