- Changed media name: yang.collection+xml/yang to application-collection+xml/json

- Modified ietf-netconf-list-pagination.yang:
     - changed get-pagable ->  get-pageable
     - renamed count -> limit
     - renamed skip -> offset
     - added import ietf-yang-metadata
     - added md:annotation remaining
This commit is contained in:
Olof hagsand 2021-08-05 18:08:32 +02:00
parent 0c7f2043f3
commit 76e59873c2
11 changed files with 57 additions and 29 deletions

View file

@ -52,7 +52,7 @@ Expected: September, 2021
* List pagination
* This is prototype work for ietf netconf work
* See draft-wwlh-netconf-list-pagination-00.txt
* New http media: application/yang.collection+xml/json
* New http media: application/yang-collection+xml/json
### API changes on existing protocol/config features
@ -549,7 +549,7 @@ Developers may need to change their code
* This is prototype work for ietf netconf work
* See draft-ietf-netconf-restconf-collection-00.txt
* New yang: ietf-restconf-collection@2020-10-22.yang
* New http media: application/yang.collection+xml/json
* New http media: application/yang-collection+xml/json
## 4.8.0
18 October 2020

View file

@ -1664,7 +1664,7 @@ from_client_get_pageable_list(clicon_handle h,
goto done;
if (xml_prefix_set(xa, "lpg") < 0)
goto done;
if (xmlns_set(x, "lpg", "urn:ietf:params:xml:ns:yang:ietf-list-pagination") < 0)
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 */
@ -2326,7 +2326,7 @@ backend_rpc_init(clicon_handle h)
#ifdef LIST_PAGINATION
/* draft-ietf-netconf-restconf-collection-00 */
if (rpc_callback_register(h, from_client_get_pageable_list, NULL,
NETCONF_COLLECTION_NAMESPACE, "get-pagable-list") < 0)
NETCONF_COLLECTION_NAMESPACE, "get-pageable-list") < 0)
goto done;
#endif
/* In backend_client.? RPC from RFC 5277 */

View file

@ -85,7 +85,7 @@ restconf_reply_header(void *req0,
int retval = -1;
restconf_stream_data *sd = (restconf_stream_data *)req0;
restconf_conn *rc;
size_t vlen;
size_t vlen;
char *value = NULL;
va_list ap;
@ -128,7 +128,7 @@ restconf_reply_header(void *req0,
/*! Send HTTP reply with potential message body
* @param[in] req http request handle
* @param[in] cb Body as a cbuf if non-NULL. Note is consumed
* @param[in] cb Body as a cbuf if non-NULL. Note: is consumed, dont free or reset after call
* @param[in] head Only send headers, dont send body.
*
* Prerequisites: status code set, headers given, body if wanted set

View file

@ -207,8 +207,8 @@ static const map_str2int http_media_map[] = {
{"application/yang-data+json", YANG_DATA_JSON},
{"application/yang-patch+xml", YANG_PATCH_XML},
{"application/yang-patch+json", YANG_PATCH_JSON},
{"application/yang.collection+xml", YANG_COLLECTION_XML},
{"application/yang.collection+json", YANG_COLLECTION_JSON},
{"application/yang-collection+xml", YANG_COLLECTION_XML},
{"application/yang-collection+json", YANG_COLLECTION_JSON},
{NULL, -1}
};

View file

@ -507,6 +507,7 @@ api_data_collection(clicon_handle h,
goto done;
if (restconf_reply_send(req, 200, cbx, 0 /* XXX head */) < 0)
goto done;
cbx = NULL; /* is consumed by above */
ok:
retval = 0;
done:

View file

@ -840,9 +840,13 @@ xml2json1_cbuf(cbuf *cb,
commas = xml_child_nr_notype(x, CX_ATTR) - 1;
for (i=0; i<xml_child_nr(x); i++){
xc = xml_child_i(x, i);
if (xml_type(xc) == CX_ATTR)
if (xml_type(xc) == CX_ATTR){
#if 1 /* Work in progress, identify md:annotations */
continue;
#else
continue; /* XXX Only xmlns attributes mapped */
#endif
}
xc_arraytype = array_eval(i?xml_child_i(x,i-1):NULL,
xc,
xml_child_i(x, i+1));

View file

@ -941,7 +941,7 @@ clicon_rpc_get_pageable_list(clicon_handle h,
cprintf(cb, " xmlns:%s=\"%s\"",
NETCONF_BASE_PREFIX, NETCONF_BASE_NAMESPACE);
cprintf(cb, " %s", NETCONF_MESSAGE_ID_ATTR);
cprintf(cb, "><get-pagable-list xmlns=\"%s\"", NETCONF_COLLECTION_NAMESPACE);
cprintf(cb, "><get-pageable-list xmlns=\"%s\"", NETCONF_COLLECTION_NAMESPACE);
/* Clixon extension, content=all,config, or nonconfig */
if ((int)content != -1)
cprintf(cb, " content=\"%s\"", netconf_content_int2str(content));
@ -965,7 +965,7 @@ clicon_rpc_get_pageable_list(clicon_handle h,
cprintf(cb, "<sort>%s</sort>", sort);
if (where)
cprintf(cb, "<where>%s</where>", where);
cprintf(cb, "</get-pagable-list></rpc>");
cprintf(cb, "</get-pageable-list></rpc>");
if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret) < 0)

View file

@ -682,7 +682,7 @@ yang_find_module_by_name(yang_stmt *yspec,
/*! Callback for handling RFC 7952 annotations
*
* a server indicates that it is prepared to handle that annotation according to the
* A server indicates that it is prepared to handle that annotation according to the
* annotation's definition. That is, an annotation advertised by the
* server may be attached to an instance of a data node defined in any
* YANG module that is implemented by the server.

View file

@ -48,11 +48,9 @@ cat <<EOF > $fexample
leaf member-id {
type string {
length "1..80";
/*
pattern '.*[\n].*' {
modifier invert-match;
}
*/
}
description
"The member's identifier.";
@ -80,11 +78,9 @@ cat <<EOF > $fexample
leaf tagline {
type string {
length "1..80";
/*
pattern '.*[\n].*' {
modifier invert-match;
}
*/
}
description
"The member's tagline.";
@ -140,11 +136,9 @@ cat <<EOF > $fexample
leaf title {
type string {
length "1..80";
/*
pattern '.*[\n].*' {
modifier invert-match;
}
*/
}
description
"A one-line title.";

View file

@ -286,17 +286,20 @@ wait_restconf
new "A.3.1.1. 'limit=1' NETCONF"
# XXX: augment GET instead, not RPC
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-pagable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore><list-target xmlns:es=\"http://example.com/ns/example-social\">/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers</list-target><limit>1</limit></get-pagable-list></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><pageable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><uint8-numbers xmlns=\"http://example.com/ns/example-social\" lpg:remaining=\"5\" xmlns:lpg=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\">17</uint8-numbers></pageable-list></rpc-reply>]]>]]>$"
#expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-pageable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore><list-target xmlns:es=\"http://example.com/ns/example-social\">/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers</list-target><limit>1</limit></get-pageable-list></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><pageable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><uint8-numbers xmlns=\"http://example.com/ns/example-social\" ycoll:remaining=\"5\" xmlns:ycoll=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\">17</uint8-numbers></pageable-list></rpc-reply>]]>]]>$"
#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-pagable-list -d "<get-pagable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore><list-target xmlns:es=\"http://example.com/ns/example-social\">/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers</list-target><limit>1</limit></get-pagable-list>")" 0 "HTTP/$HVER 200" "Content-Type: application/yang-collection+xml" foo
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" "<pageable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><uint8-numbers xmlns=\"http://example.com/ns/example-social\" lpg:remaining=\"5\" xmlns:lpg=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\">17</uint8-numbers></pageable-list>"
new "A.3.1.2. 'limit=2' NETCONF"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-pagable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore><list-target xmlns:es=\"http://example.com/ns/example-social\">/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers</list-target><limit>2</limit></get-pagable-list></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><pageable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><uint8-numbers xmlns=\"http://example.com/ns/example-social\" lpg:remaining=\"4\" xmlns:lpg=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\">17</uint8-numbers><uint8-numbers xmlns=\"http://example.com/ns/example-social\">13</uint8-numbers></pageable-list></rpc-reply>]]>]]>$"
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 "<get-pageable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore><list-target xmlns:es=\"http://example.com/ns/example-social\">/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers</list-target><limit>1</limit></get-pageable-list>")" 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 "$DEFAULTHELLO<rpc $DEFAULTNS><get-pageable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore><list-target xmlns:es=\"http://example.com/ns/example-social\">/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers</list-target><limit>2</limit></get-pageable-list></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><pageable-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination\"><uint8-numbers xmlns=\"http://example.com/ns/example-social\" lpg:remaining=\"4\" xmlns:lpg=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\">17</uint8-numbers><uint8-numbers xmlns=\"http://example.com/ns/example-social\">13</uint8-numbers></pageable-list></rpc-reply>]]>]]>$"
# CLI
# XXX This relies on a very specific clispec command: need a more generic test
@ -305,7 +308,7 @@ exit
# draft-wwlh-netconf-list-pagination-rc-00.txt
#new "A.1. 'count' Parameter RESTCONF"
#expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang.collection+xml" $RCPROTO://localhost/restconf/data/example-module:get-list-pagination/library/artist=Foo%20Fighters/album/?count=2)" 0 "HTTP/1.1 200 OK" "application/yang.collection+xml" '<collection xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-collection"><album xmlns="http://example.com/ns/example-jukebox"><name>Crime and Punishment</name><year>1995</year></album><album xmlns="http://example.com/ns/example-jukebox"><name>One by One</name><year>2002</year></album></collection>'
#expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-collection+xml" $RCPROTO://localhost/restconf/data/example-module:get-list-pagination/library/artist=Foo%20Fighters/album/?count=2)" 0 "HTTP/1.1 200 OK" "application/yang-collection+xml" '<collection xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-collection"><album xmlns="http://example.com/ns/example-jukebox"><name>Crime and Punishment</name><year>1995</year></album><album xmlns="http://example.com/ns/example-jukebox"><name>One by One</name><year>2002</year></album></collection>'
if [ $RC -ne 0 ]; then
new "Kill restconf daemon"

View file

@ -30,6 +30,11 @@ module ietf-netconf-list-pagination {
"RFC 8342: Network Management Datastore Architecture
(NMDA)";
}
import ietf-yang-metadata {
prefix "md";
reference
"RFC 7952: Defining and Using Metadata with YANG";
}
organization
"IETF NETCONF (Network Configuration) Working Group";
@ -63,7 +68,15 @@ module ietf-netconf-list-pagination {
(https://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 8526; see
the RFC itself for full legal notices.";
the RFC itself for full legal notices.
Clixon:
- changed get-pagable -> get-pageable
- renamed count -> limit
- renamed skip -> offset
- added import ietf-yang-metadata
- added md:annotation remaining
";
revision 2020-10-30 {
description
"Initial revision.";
@ -89,8 +102,21 @@ module ietf-netconf-list-pagination {
RFC 8526: NETCONF Extensions to Support the Network Management
Datastore Architecture, Section 3.1.1.2";
}
// Annotations
md:annotation remaining {
type uint32;
description
"This annotation contains the number of elements removed
from a result set after a 'limit' or 'sublist-limit'
operation. If no elements were removed, this annotation
MUST NOT appear. The minimum value (0), which never
occurs in normal operation, is reserved to represent
'unknown'. The maximum value (2^32-1) is reserved to
represent any value greater than or equal to 2^32-1
elements.";
}
rpc get-pagable-list {
rpc get-pageable-list {
description
"Use enhanced filtering features to retrieve data from a
specific NMDA datastore. The content returned by get-data