- 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:
parent
0c7f2043f3
commit
76e59873c2
11 changed files with 57 additions and 29 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.";
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue