idnits 2.17.00 (12 Aug 2021)
/tmp/idnits34800/draft-wwlh-netconf-list-pagination-00.txt:
Checking boilerplate required by RFC 5378 and the IETF Trust (see
https://trustee.ietf.org/license-info):
----------------------------------------------------------------------------
No issues found here.
Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt:
----------------------------------------------------------------------------
No issues found here.
Checking nits according to https://www.ietf.org/id-info/checklist :
----------------------------------------------------------------------------
No issues found here.
Miscellaneous warnings:
----------------------------------------------------------------------------
== The copyright year in the IETF Trust and authors Copyright Line does not
match the current year
== Line 843 has weird spacing: '...argeted desce...'
== Line 990 has weird spacing: '...mestamp yan...'
== Line 1002 has weird spacing: '...p-level enu...'
== Line 1006 has weird spacing: '...mestamp yan...'
== Line 1007 has weird spacing: '...mber-id str...'
== (1 more instance...)
-- The document date (25 October 2021) is 201 days in the past. Is this
intentional?
Checking references for intended status: Proposed Standard
----------------------------------------------------------------------------
(See RFCs 3967 and 4897 for information about using normative references
to lower-maturity documents in RFCs)
-- Looks like a reference, but probably isn't: '17' on line 2097
-- Looks like a reference, but probably isn't: '13' on line 1829
-- Looks like a reference, but probably isn't: '11' on line 1829
-- Looks like a reference, but probably isn't: '7' on line 1829
-- Looks like a reference, but probably isn't: '5' on line 1829
-- Looks like a reference, but probably isn't: '3' on line 1829
== Missing Reference: '-5' is mentioned on line 2098, but not defined
== Missing Reference: '-3' is mentioned on line 1393, but not defined
== Missing Reference: '-1' is mentioned on line 1393, but not defined
-- Looks like a reference, but probably isn't: '1' on line 1393
== Outdated reference: draft-ietf-netconf-notification-capabilities has
been published as RFC 9196
Summary: 0 errors (**), 0 flaws (~~), 11 warnings (==), 8 comments (--).
Run idnits with the --verbose option for more detailed information about
the items above.
--------------------------------------------------------------------------------
2 NETCONF Working Group K. Watsen
3 Internet-Draft Watsen Networks
4 Intended status: Standards Track Q. Wu
5 Expires: 28 April 2022 Huawei Technologies
6 O. Hagsand
7 Netgate
8 H. Li
9 Hewlett Packard Enterprise
10 P. Andersson
11 Cisco Systems
12 25 October 2021
14 List Pagination for YANG-driven Protocols
15 draft-wwlh-netconf-list-pagination-00
17 Abstract
19 In some circumstances, instances of YANG modeled "list" and "leaf-
20 list" nodes may contain numerous entries. Retrieval of all the
21 entries can lead to inefficiencies in the server, the client, and the
22 network in between.
24 This document defines a model for list pagination that can be
25 implemented by YANG-driven management protocols such as NETCONF and
26 RESTCONF. The model supports paging over optionally filtered and/or
27 sorted entries. The solution additionally enables servers to
28 constrain query expressions on some "config false" lists or leaf-
29 lists.
31 Status of This Memo
33 This Internet-Draft is submitted in full conformance with the
34 provisions of BCP 78 and BCP 79.
36 Internet-Drafts are working documents of the Internet Engineering
37 Task Force (IETF). Note that other groups may also distribute
38 working documents as Internet-Drafts. The list of current Internet-
39 Drafts is at https://datatracker.ietf.org/drafts/current/.
41 Internet-Drafts are draft documents valid for a maximum of six months
42 and may be updated, replaced, or obsoleted by other documents at any
43 time. It is inappropriate to use Internet-Drafts as reference
44 material or to cite them other than as "work in progress."
46 This Internet-Draft will expire on 28 April 2022.
48 Copyright Notice
50 Copyright (c) 2021 IETF Trust and the persons identified as the
51 document authors. All rights reserved.
53 This document is subject to BCP 78 and the IETF Trust's Legal
54 Provisions Relating to IETF Documents (https://trustee.ietf.org/
55 license-info) in effect on the date of publication of this document.
56 Please review these documents carefully, as they describe your rights
57 and restrictions with respect to this document. Code Components
58 extracted from this document must include Simplified BSD License text
59 as described in Section 4.e of the Trust Legal Provisions and are
60 provided without warranty as described in the Simplified BSD License.
62 Table of Contents
64 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
65 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4
66 1.2. Conventions . . . . . . . . . . . . . . . . . . . . . . . 4
67 1.3. Adherence to the NMDA . . . . . . . . . . . . . . . . . . 4
68 2. Solution Overview . . . . . . . . . . . . . . . . . . . . . . 4
69 3. Solution Details . . . . . . . . . . . . . . . . . . . . . . 5
70 3.1. Query Parameters for a Targeted List or Leaf-List . . . . 5
71 3.2. Query Parameter for Descendant Lists and Leaf-Lists . . . 8
72 3.3. Constraints on "where" and "sort-by" for "config false"
73 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 9
74 3.3.1. Identifying Constrained "config false" Lists and
75 Leaf-Lists . . . . . . . . . . . . . . . . . . . . . 10
76 3.3.2. Indicating the Constraints for "where" Filters and
77 "sort-by" Expressions . . . . . . . . . . . . . . . . 10
78 4. The "ietf-list-pagination" Module . . . . . . . . . . . . . . 11
79 4.1. Data Model Overview . . . . . . . . . . . . . . . . . . . 11
80 4.2. Example Usage . . . . . . . . . . . . . . . . . . . . . . 12
81 4.2.1. Constraining a "config false" list . . . . . . . . . 12
82 4.2.2. Indicating number remaining in a limited list . . . . 12
83 4.3. YANG Module . . . . . . . . . . . . . . . . . . . . . . . 12
84 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 19
85 5.1. The "IETF XML" Registry . . . . . . . . . . . . . . . . . 19
86 5.2. The "YANG Module Names" Registry . . . . . . . . . . . . 19
87 6. Security Considerations . . . . . . . . . . . . . . . . . . . 19
88 6.1. Regarding the "ietf-list-pagination" YANG Module . . . . 19
89 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 19
90 7.1. Normative References . . . . . . . . . . . . . . . . . . 20
91 7.2. Informative References . . . . . . . . . . . . . . . . . 20
92 Appendix A. Vector Tests . . . . . . . . . . . . . . . . . . . . 21
93 A.1. Example YANG Module . . . . . . . . . . . . . . . . . . . 21
94 A.2. Example Data Set . . . . . . . . . . . . . . . . . . . . 28
95 A.3. Example Queries . . . . . . . . . . . . . . . . . . . . . 32
96 A.3.1. The "limit" Parameter . . . . . . . . . . . . . . . . 33
97 A.3.2. The "offset" Parameter . . . . . . . . . . . . . . . 35
98 A.3.3. The "direction" Parameter . . . . . . . . . . . . . . 38
99 A.3.4. The "sort-by" Parameter . . . . . . . . . . . . . . . 39
100 A.3.5. The "where" Parameter . . . . . . . . . . . . . . . . 42
101 A.3.6. The "sublist-limit" Parameter . . . . . . . . . . . . 44
102 A.3.7. Combinations of Parameters . . . . . . . . . . . . . 48
103 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 50
104 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 50
106 1. Introduction
108 YANG modeled "list" and "leaf-list" nodes may contain a large number
109 of entries. For instance, there may be thousands of entries in the
110 configuration for network interfaces or access control lists. And
111 time-driven logging mechanisms, such as an audit log or a traffic
112 log, can contain millions of entries.
114 Retrieval of all the entries can lead to inefficiencies in the
115 server, the client, and the network in between. For instance,
116 consider the following:
118 * A client may need to filter and/or sort list entries in order to,
119 e.g., present the view requested by a user.
121 * A server may need to iterate over many more list entries than
122 needed by a client.
124 * A network may need to convey more data than needed by a client.
126 Optimal global resource utilization is obtained when clients are able
127 to cherry-pick just that which is needed to support the application-
128 level business logic.
130 This document defines a generic model for list pagination that can be
131 implemented by YANG-driven management protocols such as NETCONF
132 [RFC6241] and RESTCONF [RFC8040]. Details for how such protocols are
133 updated are outside the scope of this document.
135 The model presented in this document supports paging over optionally
136 filtered and/or sorted entries. Server-side filtering and sorting is
137 ideal as servers can leverage indexes maintained by a backend storage
138 layer to accelerate queries.
140 1.1. Terminology
142 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
143 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
144 "OPTIONAL" in this document are to be interpreted as described in BCP
145 14 [RFC2119] [RFC8174] when, and only when, they appear in all
146 capitals, as shown here.
148 The following terms are defined in [RFC7950] and are not redefined
149 here: client, data model, data tree, feature, extension, module,
150 leaf, leaf-list, and server.
152 1.2. Conventions
154 Various examples used in this document use a placeholder value for
155 binary data that has been base64 encoded (e.g., "BASE64VALUE=").
156 This placeholder value is used as real base64 encoded structures are
157 often many lines long and hence distracting to the example being
158 presented.
160 1.3. Adherence to the NMDA
162 This document is compliant with the Network Management Datastore
163 Architecture (NMDA) [RFC8342]. The "ietf-list-pagination" module
164 only defines a YANG extension and augments a couple leafs into a
165 "config false" node defined by the "ietf-system-capabilities" module.
167 2. Solution Overview
169 The solution presented in this document broadly entails a client
170 sending a query to a server targeting a specific list or leaf-list
171 including optional parameters guiding which entries should be
172 returned.
174 A secondary aspect of this solution entails a client sending a query
175 parameter to a server guiding how descendent lists and leaf-lists
176 should be returned. This parameter may be used on any target node,
177 not just "list" and "leaf-list" nodes.
179 Clients detect a server's support for list pagination via an entry
180 for the "ietf-list-pagination" module (defined in Section 4) in the
181 server's YANG Library [RFC8525] response.
183 Relying on client-provided query parameters ensures servers remain
184 backward compatible with legacy clients.
186 3. Solution Details
188 This section is composed of the following subsections:
190 * Section 3.1 defines five query parameters clients may use to page
191 through the entries of a single list or leaf-list in a data tree.
193 * Section 3.2 defines one query parameter that clients may use to
194 affect the content returned for descendant lists and leaf-lists.
196 * Section 3.3 defines per schema-node tags enabling servers to
197 indicate which "config false" lists are constrained and how they
198 may be interacted with.
200 3.1. Query Parameters for a Targeted List or Leaf-List
202 The five query parameters presented this section are listed in
203 processing order. This processing order is logical, efficient, and
204 matches the processing order implemented by database systems, such as
205 SQL.
207 The order is as follows: a server first processes the "where"
208 parameter (see Section 3.1.1), then the "sort-by" parameter (see
209 Section 3.1.2), then the "direction" parameter (see Section 3.1.3),
210 then the "offset" parameter (see Section 3.1.4), and lastly the
211 "limit" parameter (see Section 3.1.5).
213 3.1.1. The "where" Query Parameter
215 Description
216 The "where" query parameter specifies a filter expression that
217 result-set entries must match.
219 Default Value
220 If this query parameter is unspecified, then no entries are
221 filtered from the working result-set.
223 Allowed Values
224 The allowed values are XPath 1.0 expressions. It is an error if
225 the XPath expression references a node identifier that does not
226 exist in the schema, is optional or conditional in the schema or,
227 for constrained "config false" lists and leaf-lists (see
228 Section 3.3), if the node identifier does not point to a node
229 having the "indexed" extension statement applied to it (see
230 Section 3.3.2).
232 Conformance
233 The "where" query parameter MUST be supported for all "config
234 true" lists and leaf-lists and SHOULD be supported for "config
235 false" lists and leaf-lists. Servers MAY disable the support for
236 some or all "config false" lists and leaf-lists as described in
237 Section 3.3.2.
239 3.1.2. The "sort-by" Query Parameter
241 Description
242 The "sort-by" query parameter indicates the node in the working
243 result-set (i.e., after the "where" parameter has been applied)
244 that entries should be sorted by. Sorts are in ascending order
245 (e.g., '1' before '9', 'a' before 'z', etc.). Missing values are
246 sorted to the end (e.g., after all nodes having values). Sub-
247 sorts are not supported.
249 Default Value
250 If this query parameter is unspecified, then the list or leaf-
251 list's default order is used, per the YANG "ordered-by" statement
252 (see Section 7.7.7 of [RFC7950]).
254 Allowed Values
255 The allowed values are node identifiers. It is an error if the
256 specified node identifier does not exist in the schema, is
257 optional or conditional in the schema or, for constrained "config
258 false" lists and leaf-lists (see Section 3.3), if the node
259 identifier does not point to a node having the "indexed" extension
260 statement applied to it (see Section 3.3.2).
262 Conformance
263 The "sort-by" query parameter MUST be supported for all "config
264 true" lists and leaf-lists and SHOULD be supported for "config
265 false" lists and leaf-lists. Servers MAY disable the support for
266 some or all "config false" lists and leaf-lists as described in
267 Section 3.3.2.
269 3.1.3. The "direction" Query Parameter
271 Description
272 The "direction" query parameter indicates how the entries in the
273 working result-set (i.e., after the "sort-by" parameter has been
274 applied) should be traversed.
276 Default Value
277 If this query parameter is unspecified, the default value is
278 "forwards".
280 Allowed Values
281 The allowed values are:
283 forwards
284 Return entries in the forwards direction. Also known as the
285 "default" or "ascending" direction.
287 backwards
288 Return entries in the backwards direction. Also known as the
289 "reverse" or "descending" direction
291 Conformance
292 The "direction" query parameter MUST be supported for all lists
293 and leaf-lists.
295 3.1.4. The "offset" Query Parameter
297 Description
298 The "offset" query parameter indicates the number of entries in
299 the working result-set (i.e., after the "direction" parameter has
300 been applied) that should be skipped over when preparing the
301 response.
303 Default Value
304 If this query parameter is unspecified, then no entries in the
305 result-set are skipped, same as when the offset value '0' is
306 specified.
308 Allowed Values
309 The allowed values are unsigned integers. It is an error for the
310 offset value to exceed the number of entries in the working
311 result-set, and the "offset-out-of-range" identity SHOULD be
312 produced in the error output when this occurs.
314 Conformance
315 The "offset" query parameter MUST be supported for all lists and
316 leaf-lists.
318 3.1.5. The "limit" Query Parameter
320 Description
321 The "limit" query parameter limits the number of entries returned
322 from the working result-set (i.e., after the "offset" parameter
323 has been applied). Any list or leaf-list that is limited
324 includes, somewhere in its encoding, a metadata value [RFC7952]
325 called "remaining", a positive integer indicating the number of
326 elements that were not included in the result-set by the "limit"
327 operation, or the value "unknown" in case, e.g., the server
328 determines that counting would be prohibitively expensive.
330 Default Value
331 If this query parameter is unspecified, the number of entries that
332 may be returned is unbounded.
334 Allowed Values
335 The allowed values are positive integers.
337 Conformance
338 The "limit" query parameter MUST be supported for all lists and
339 leaf-lists.
341 3.2. Query Parameter for Descendant Lists and Leaf-Lists
343 Whilst this document primarily regards pagination for a list or leaf-
344 list, it begs the question for how descendant lists and leaf-lists
345 should be handled, which is addressed by the "sublist-limit" query
346 parameter described in this section.
348 3.2.1. The "sublist-limit" Query Parameter
350 Description
351 The "sublist-limit" parameter limits the number of entries
352 returned for descendent lists and leaf-lists.
354 Any descendent list or leaf-list limited by the "sublist-limit"
355 parameter includes, somewhere in its encoding, a metadata value
356 [RFC7952] called "remaining", a positive integer indicating the
357 number of elements that were not included by the "sublist-limit"
358 parameter, or the value "unknown" in case, e.g., the server
359 determines that counting would be prohibitively expensive.
361 When used on a list node, it only affects the list's descendant
362 nodes, not the list itself, which is only affected by the
363 parameters presented in Section 3.1.
365 Default Value
366 If this query parameter is unspecified, the number of entries that
367 may be returned for descendent lists and leaf-lists is unbounded.
369 Allowed Values
370 The allowed values are positive integers.
372 Conformance
373 The "sublist-limit" query parameter MUST be supported for all
374 conventional nodes, including a datastore's top-level node (i.e.,
375 '/').
377 3.3. Constraints on "where" and "sort-by" for "config false" Lists
379 Some "config false" lists and leaf-lists may contain an enormous
380 number of entries. For instance, a time-driven logging mechanism,
381 such as an audit log or a traffic log, can contain millions of
382 entries.
384 In such cases, "where" and "sort-by" expressions will not perform
385 well if the server must bring each entry into memory in order to
386 process it.
388 The server's best option is to leverage query-optimizing features
389 (e.g., indexes) built into the backend database holding the dataset.
391 However, arbitrary "where" expressions and "sort-by" node identifiers
392 into syntax supported by the backend database and/or query-optimizers
393 may prove challenging, if not impossible, to implement.
395 Thusly this section introduces mechanisms whereby a server can:
397 1. Identify which "config false" lists and leaf-lists are
398 constrained.
400 2. Identify what node-identifiers and expressions are allowed for
401 the constrained lists and leaf-lists.
403 | Note: The pagination performance for "config true" lists and
404 | leaf-lists is not considered as already servers must be able to
405 | process them as configuration. Whilst some "config true' lists
406 | and leaf-lists may contain thousands of entries, they are well
407 | within the capability of server-side processing.
409 3.3.1. Identifying Constrained "config false" Lists and Leaf-Lists
411 Identification of which lists and leaf-lists are constrained occurs
412 in the schema tree, not the data tree. However, as server abilities
413 vary, it is not possible to define constraints in YANG modules
414 defining generic data models.
416 In order to enable servers to identify which lists and leaf-lists are
417 constrained, the solution presented in this document augments the
418 data model defined by the "ietf-system-capabilities" module presented
419 in [I-D.ietf-netconf-notification-capabilities].
421 Specifically, the "ietf-list-pagination" module (see Section 4)
422 augments an empty leaf node called "constrained" into the "per-node-
423 capabilities" node defined in the "ietf-system-capabilities" module.
425 The "constrained" leaf MAY be specified for any "config false" list
426 or leaf-list.
428 When a list or leaf-list is constrained:
430 * All parts of XPath 1.0 expressions are disabled unless explicitly
431 enabled by Section 3.3.2.
433 * Node-identifiers used in "where" expressions and "sort-by" filters
434 MUST have the "indexed" leaf applied to it (see Section 3.3.2).
436 * For lists only, node-identifiers used in "where" expressions and
437 "sort-by" filters MUST NOT descend past any descendent lists.
438 This ensures that only indexes relative to the targeted list are
439 used. Further constraints on node identifiers MAY be applied in
440 Section 3.3.2.
442 3.3.2. Indicating the Constraints for "where" Filters and "sort-by"
443 Expressions
445 This section identifies how constraints for "where" filters and
446 "sort-by" expressions are specified. These constraints are valid
447 only if the "constrained" leaf described in the previous section
448 Section 3.3.1 has been set on the immediate ancestor "list" node or,
449 for "leaf-list" nodes, on itself.
451 3.3.2.1. Indicating Filterable/Sortable Nodes
453 For "where" filters, an unconstrained XPath expressions may use any
454 node in comparisons. However, efficient mappings to backend
455 databases may support only a subset of the nodes.
457 Similarly, for "sort-by" expressions, efficient sorts may only
458 support a subset of the nodes.
460 In order to enable servers to identify which nodes may be used in
461 comparisons (for both "where" and "sort-by" expressions), the "ietf-
462 list-pagination" module (see Section 4) augments an empty leaf node
463 called "indexed" into the "per-node-capabilities" node defined in the
464 "ietf-system-capabilities" module (see
465 [I-D.ietf-netconf-notification-capabilities]).
467 When a "list" or "leaf-list" node has the "constrained" leaf, only
468 nodes having the "indexed" node may be used in "where" and/or "sort-
469 by" expressions. If no nodes have the "indexed" leaf, when the
470 "constrained" leaf is present, then "where" and "sort-by" expressions
471 are disabled for that list or leaf-list.
473 4. The "ietf-list-pagination" Module
475 The "ietf-list-pagination" module is used by servers to indicate that
476 they support pagination on YANG "list" and "leaf-list" nodes, and to
477 provide an ability to indicate which "config false" list and/or
478 "leaf-list" nodes are constrained and, if so, which nodes may be used
479 in "where" and "sort-by" expressions.
481 4.1. Data Model Overview
483 The following tree diagram [RFC8340] illustrates the "ietf-list-
484 pagination" module:
486 module: ietf-list-pagination
488 augment /sysc:system-capabilities/sysc:datastore-capabilities
489 /sysc:per-node-capabilities:
490 +--ro constrained? empty
491 +--ro indexed? empty
493 Comments:
495 * As shown, this module augments two optional leaves into the "node-
496 selector" node of the "ietf-system-capabilities" module.
498 * Not shown is that the module also defines an "md:annotation"
499 statement named "remaining". This annotation may be present in a
500 server's response to a client request containing either the
501 "limit" (Section 3.1.5) or "sublist-limit" parameters
502 (Appendix A.3.6).
504 4.2. Example Usage
506 4.2.1. Constraining a "config false" list
508 The following example illustrates the "ietf-list-pagination" module's
509 augmentations of the "system-capabilities" data tree. This example
510 assumes the "example-social" module defined in the Appendix A.1 is
511 implemented.
513 =============== NOTE: '\' line wrapping per RFC 8792 ================
515
520
521 ds:operational
522
523 /es:audit-logs/es:audit-log
524
525
526
527 /es:audit-logs/es:audit-log/es:timestamp
529
530
531
532 /es:audit-logs/es:audit-log/es:member-id
534
535
536
537 /es:audit-logs/es:audit-log/es:outcome
539
540
541
542
544 4.2.2. Indicating number remaining in a limited list
546 FIXME: valid syntax for 'where'?
548 4.3. YANG Module
550 This YANG module has normative references to [RFC7952] and
551 [I-D.ietf-netconf-notification-capabilities].
553 file "ietf-list-pagination@2021-10-25.yang"
555 module ietf-list-pagination {
556 yang-version 1.1;
557 namespace
558 "urn:ietf:params:xml:ns:yang:ietf-list-pagination";
559 prefix lpg;
561 import ietf-yang-types {
562 prefix yang;
563 reference
564 "RFC 6991: Common YANG Data Types";
565 }
567 import ietf-yang-metadata {
568 prefix md;
569 reference
570 "RFC 7952: Defining and Using Metadata with YANG";
571 }
573 import ietf-system-capabilities {
574 prefix sysc;
575 reference
576 "draft-ietf-netconf-notification-capabilities:
577 YANG Modules describing Capabilities for
578 Systems and Datastore Update Notifications";
579 }
581 organization
582 "IETF NETCONF (Network Configuration) Working Group";
584 contact
585 "WG Web:
586 WG List: ";
588 description
589 "This module is used by servers to 1) indicate they support
590 pagination on 'list' and 'leaf-list' resources, 2) define a
591 grouping for each list-pagination parameter, and 3) indicate
592 which 'config false' lists have constrained 'where' and
593 'sort-by' parameters and how they may be used, if at all.
595 Copyright (c) 2021 IETF Trust and the persons identified
596 as authors of the code. All rights reserved.
598 Redistribution and use in source and binary forms, with
599 or without modification, is permitted pursuant to, and
600 subject to the license terms contained in, the Simplified
601 BSD License set forth in Section 4.c of the IETF Trust's
602 Legal Provisions Relating to IETF Documents
603 (https://trustee.ietf.org/license-info).
605 This version of this YANG module is part of RFC XXXX
606 (https://www.rfc-editor.org/info/rfcXXXX); see the RFC
607 itself for full legal notices.
609 The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
610 'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED',
611 'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document
612 are to be interpreted as described in BCP 14 (RFC 2119)
613 (RFC 8174) when, and only when, they appear in all
614 capitals, as shown here.";
616 revision 2021-10-25 {
617 description
618 "Initial revision.";
619 reference
620 "RFC XXXX: List Pagination for YANG-driven Protocols";
621 }
623 // Annotations
625 md:annotation remaining {
626 type union {
627 type uint32;
628 type enumeration {
629 enum "unknown" {
630 description
631 "Indicates that number of remaining entries is unknown
632 to the server in case, e.g., the server has determined
633 that counting would be prohibitively expensive.";
634 }
635 }
636 }
637 description
638 "This annotation contains the number of elements not included
639 in the result set (a positive value) due to a 'limit' or
640 'sublist-limit' operation. If no elements were removed,
641 this annotation MUST NOT appear. The minimum value (0),
642 which never occurs in normal operation, is reserved to
643 represent 'unknown'. The maximum value (2^32-1) is
644 reserved to represent any value greater than or equal
645 to 2^32-1 elements.";
646 }
647 // Identities
649 identity list-pagination-error {
650 description
651 "Base identity for list-pagination errors.";
652 }
654 identity offset-out-of-range {
655 base list-pagination-error;
656 description
657 "The 'offset' query parameter value is greater than the number
658 of instances in the target list or leaf-list resource.";
659 }
661 // Groupings
663 grouping where-param-grouping {
664 description
665 "This grouping may be used by protocol-specific YANG modules
666 to define a protocol-specific query parameter.";
667 leaf where {
668 type union {
669 type yang:xpath1.0;
670 type enumeration {
671 enum "unfiltered" {
672 description
673 "Indicates that no entries are to be filtered
674 from the working result-set.";
675 }
676 }
677 }
678 default "unfiltered";
679 description
680 "The 'where' parameter specifies a boolean expression
681 that result-set entries must match.
683 It is an error if the XPath expression references a node
684 identifier that does not exist in the schema, is optional
685 or conditional in the schema or, for constrained 'config
686 false' lists and leaf-lists, if the node identifier does
687 not point to a node having the 'indexed' extension
688 statement applied to it (see RFC XXXX).";
689 }
690 }
692 grouping sort-by-param-grouping {
693 description
694 "This grouping may be used by protocol-specific YANG modules
695 to define a protocol-specific query parameter.";
696 leaf sort-by {
697 type union {
698 type string {
699 // An RFC 7950 'descendant-schema-nodeid'.
700 pattern '([0-9a-fA-F]*:)?[0-9a-fA-F]*'
701 + '(/([0-9a-fA-F]*:)?[0-9a-fA-F]*)*';
702 }
703 type enumeration {
704 enum "none" {
705 description
706 "Indicates that the list or leaf-list's default
707 order is to be used, per the YANG 'ordered-by'
708 statement.";
709 }
710 }
711 }
712 default "none";
713 description
714 "The 'sort-by' parameter indicates the node in the
715 working result-set (i.e., after the 'where' parameter
716 has been applied) that entries should be sorted by.
718 Sorts are in ascending order (e.g., '1' before '9',
719 'a' before 'z', etc.). Missing values are sorted to
720 the end (e.g., after all nodes having values).";
721 }
722 }
724 grouping direction-param-grouping {
725 description
726 "This grouping may be used by protocol-specific YANG modules
727 to define a protocol-specific query parameter.";
728 leaf direction {
729 type enumeration {
730 enum forwards {
731 description
732 "Indicates that entries should be traversed from
733 the first to last item in the working result set.";
734 }
735 enum backwards {
736 description
737 "Indicates that entries should be traversed from
738 the last to first item in the working result set.";
739 }
740 }
741 default "forwards";
742 description
743 "The 'direction' parameter indicates how the entries in the
744 working result-set (i.e., after the 'sort-by' parameter
745 has been applied) should be traversed.";
746 }
747 }
749 grouping offset-param-grouping {
750 description
751 "This grouping may be used by protocol-specific YANG modules
752 to define a protocol-specific query parameter.";
753 leaf offset {
754 type uint32;
755 default 0;
756 description
757 "The 'offset' parameter indicates the number of entries
758 in the working result-set (i.e., after the 'direction'
759 parameter has been applied) that should be skipped over
760 when preparing the response.";
761 }
762 }
764 grouping limit-param-grouping {
765 description
766 "This grouping may be used by protocol-specific YANG modules
767 to define a protocol-specific query parameter.";
768 leaf limit {
769 type union {
770 type uint32 {
771 range "1..max";
772 }
773 type enumeration {
774 enum "unbounded" {
775 description
776 "Indicates that the number of entries that may be
777 returned is unbounded.";
778 }
779 }
780 }
781 default "unbounded";
782 description
783 "The 'limit' parameter limits the number of entries returned
784 from the working result-set (i.e., after the 'offset'
785 parameter has been applied).
787 Any result-set that is limited includes, somewhere in its
788 encoding, the metadata value 'remaining' to indicate the
789 number entries not included in the result set.";
790 }
792 }
794 grouping sublist-limit-param-grouping {
795 description
796 "This grouping may be used by protocol-specific YANG modules
797 to define a protocol-specific query parameter.";
798 leaf sublist-limit {
799 type union {
800 type uint32 {
801 range "1..max";
802 }
803 type enumeration {
804 enum "unbounded" {
805 description
806 "Indicates that the number of entries that may be
807 returned is unbounded.";
808 }
809 }
810 }
811 default "unbounded";
812 description
813 "The 'sublist-limit' parameter limits the number of entries
814 for descendent lists and leaf-lists.
816 Any result-set that is limited includes, somewhere in
817 its encoding, the metadata value 'remaining' to indicate
818 the number entries not included in the result set.";
819 }
820 }
822 // Protocol-accessible nodes
824 augment // FIXME: ensure datastore ==
825 "/sysc:system-capabilities/sysc:datastore-capabilities"
826 + "/sysc:per-node-capabilities" {
827 description
828 "Defines some leafs that MAY be used by the server to
829 describe constraints imposed of the 'where' filters and
830 'sort-by' parameters used in list pagination queries.";
831 leaf constrained {
832 type empty;
833 description
834 "Indicates that 'where' filters and 'sort-by' parameters
835 on the targeted 'config false' list node are constrained.
836 If a list is not 'constrained', then full XPath 1.0
837 expressions may be used in 'where' filters and all node
838 identifiers are usable by 'sort-by'.";
839 }
840 leaf indexed {
841 type empty;
842 description
843 "Indicates that the targeted descendent node of a
844 'constrained' list (see the 'constrained' leaf) may be
845 used in 'where' filters and/or 'sort-by' parameters.
846 If a descendent node of a 'constrained' list is not
847 'indexed', then it MUST NOT be used in 'where' filters
848 or 'sort-by' parameters.";
849 }
850 }
851 }
853
855 5. IANA Considerations
857 5.1. The "IETF XML" Registry
859 This document registers one URI in the "ns" subregistry of the IETF
860 XML Registry [RFC3688] maintained at
861 https://www.iana.org/assignments/xml-registry/xml-registry.xhtml#ns.
862 Following the format in [RFC3688], the following registration is
863 requested:
865 URI: urn:ietf:params:xml:ns:yang:ietf-list-pagination
866 Registrant Contact: The IESG.
867 XML: N/A, the requested URI is an XML namespace.
869 5.2. The "YANG Module Names" Registry
871 This document registers one YANG module in the YANG Module Names
872 registry [RFC6020] maintained at https://www.iana.org/assignments/
873 yang-parameters/yang-parameters.xhtml. Following the format defined
874 in [RFC6020], the below registration is requested:
876 name: ietf-list-pagination
877 namespace: urn:ietf:params:xml:ns:yang:ietf-list-pagination
878 prefix: lpg
879 RFC: XXXX
881 6. Security Considerations
883 6.1. Regarding the "ietf-list-pagination" YANG Module
885 Pursuant the template defined in ...FIXME
887 7. References
888 7.1. Normative References
890 [I-D.ietf-netconf-notification-capabilities]
891 Lengyel, B., Clemm, A., and B. Claise, "YANG Modules
892 describing Capabilities for Systems and Datastore Update
893 Notifications", Work in Progress, Internet-Draft, draft-
894 ietf-netconf-notification-capabilities-21, 15 October
895 2021, .
898 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
899 Requirement Levels", BCP 14, RFC 2119,
900 DOI 10.17487/RFC2119, March 1997,
901 .
903 [RFC3688] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
904 DOI 10.17487/RFC3688, January 2004,
905 .
907 [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language",
908 RFC 7950, DOI 10.17487/RFC7950, August 2016,
909 .
911 [RFC7952] Lhotka, L., "Defining and Using Metadata with YANG",
912 RFC 7952, DOI 10.17487/RFC7952, August 2016,
913 .
915 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
916 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
917 May 2017, .
919 7.2. Informative References
921 [RFC6020] Bjorklund, M., Ed., "YANG - A Data Modeling Language for
922 the Network Configuration Protocol (NETCONF)", RFC 6020,
923 DOI 10.17487/RFC6020, October 2010,
924 .
926 [RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed.,
927 and A. Bierman, Ed., "Network Configuration Protocol
928 (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011,
929 .
931 [RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF
932 Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017,
933 .
935 [RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams",
936 BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018,
937 .
939 [RFC8342] Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K.,
940 and R. Wilton, "Network Management Datastore Architecture
941 (NMDA)", RFC 8342, DOI 10.17487/RFC8342, March 2018,
942 .
944 [RFC8525] Bierman, A., Bjorklund, M., Schoenwaelder, J., Watsen, K.,
945 and R. Wilton, "YANG Library", RFC 8525,
946 DOI 10.17487/RFC8525, March 2019,
947 .
949 Appendix A. Vector Tests
951 This normative appendix section illustrates every notable edge
952 condition conceived during this document's production.
954 Test inputs and outputs are provided in a manner that is both generic
955 and concise.
957 Management protocol specific documents need only reproduce as many of
958 these tests as necessary to convey pecularities presented by the
959 protocol.
961 Implementations are RECOMMENDED to implement the tests presented in
962 this document, in addition to any tests that may be presented in
963 protocol specific documents.
965 A.1. Example YANG Module
967 The vector tests assume the "example-social" YANG module defined in
968 this section.
970 This module has been specially crafted to cover every notable edge
971 condition, especially with regards to the types of the data nodes.
973 Following is the tree diagram [RFC8340] for the "example-social"
974 module:
976 module: example-social
977 +--rw members
978 | +--rw member* [member-id]
979 | +--rw member-id string
980 | +--rw email-address inet:email-address
981 | +--rw password ianach:crypt-hash
982 | +--rw avatar? binary
983 | +--rw tagline? string
984 | +--rw privacy-settings
985 | | +--rw hide-network? boolean
986 | | +--rw post-visibility? enumeration
987 | +--rw following* -> /members/member/member-id
988 | +--rw posts
989 | | +--rw post* [timestamp]
990 | | +--rw timestamp yang:date-and-time
991 | | +--rw title? string
992 | | +--rw body string
993 | +--rw favorites
994 | | +--rw uint8-numbers* uint8
995 | | +--rw uint64-numbers* uint64
996 | | +--rw int8-numbers* int8
997 | | +--rw int64-numbers* int64
998 | | +--rw decimal64-numbers* decimal64
999 | | +--rw bits* bits
1000 | +--ro stats
1001 | +--ro joined yang:date-and-time
1002 | +--ro membership-level enumeration
1003 | +--ro last-activity? yang:date-and-time
1004 +--ro audit-logs
1005 +--ro audit-log* []
1006 +--ro timestamp yang:date-and-time
1007 +--ro member-id string
1008 +--ro source-ip inet:ip-address
1009 +--ro request string
1010 +--ro outcome boolean
1012 Following is the YANG [RFC7950] for the "example-social" module:
1014 module example-social {
1015 yang-version 1.1;
1016 namespace "http://example.com/ns/example-social";
1017 prefix es;
1019 import ietf-yang-types {
1020 prefix yang;
1021 reference
1022 "RFC 6991: Common YANG Data Types";
1023 }
1024 import ietf-inet-types {
1025 prefix inet;
1026 reference
1027 "RFC 6991: Common YANG Data Types";
1028 }
1030 import iana-crypt-hash {
1031 prefix ianach;
1032 reference
1033 "RFC 7317: A YANG Data Model for System Management";
1034 }
1036 organization "Example, Inc.";
1037 contact "support@example.com";
1038 description "Example Social Data Model.";
1040 revision YYYY-MM-DD {
1041 description
1042 "Initial version.";
1043 reference
1044 "RFC XXXX: Example social module.";
1045 }
1047 container members {
1048 description
1049 "Container for list of members.";
1050 list member {
1051 key "member-id";
1052 description
1053 "List of members.";
1055 leaf member-id {
1056 type string {
1057 length "1..80";
1058 pattern '.*[\n].*' {
1059 modifier invert-match;
1060 }
1061 }
1062 description
1063 "The member's identifier.";
1064 }
1066 leaf email-address {
1067 type inet:email-address;
1068 mandatory true;
1069 description
1070 "The member's email address.";
1071 }
1072 leaf password {
1073 type ianach:crypt-hash;
1074 mandatory true;
1075 description
1076 "The member's hashed-password.";
1077 }
1079 leaf avatar {
1080 type binary;
1081 description
1082 "An binary image file.";
1083 }
1085 leaf tagline {
1086 type string {
1087 length "1..80";
1088 pattern '.*[\n].*' {
1089 modifier invert-match;
1090 }
1091 }
1092 description
1093 "The member's tagline.";
1094 }
1096 container privacy-settings {
1097 leaf hide-network {
1098 type boolean;
1099 description
1100 "Hide who you follow and who follows you.";
1101 }
1102 leaf post-visibility {
1103 type enumeration {
1104 enum public {
1105 description
1106 "Posts are public.";
1107 }
1108 enum unlisted {
1109 description
1110 "Posts are unlisted, though visable to all.";
1111 }
1112 enum followers-only {
1113 description
1114 "Posts only visible to followers.";
1115 }
1116 }
1117 default public;
1118 description
1119 "The post privacy setting.";
1121 }
1122 description
1123 "Preferences for the member.";
1124 }
1126 leaf-list following {
1127 type leafref {
1128 path "/members/member/member-id";
1129 }
1130 description
1131 "Other members this members is following.";
1132 }
1134 container posts {
1135 description
1136 "The member's posts.";
1137 list post {
1138 key timestamp;
1139 leaf timestamp {
1140 type yang:date-and-time;
1141 description
1142 "The timestamp for the member's post.";
1143 }
1144 leaf title {
1145 type string {
1146 length "1..80";
1147 pattern '.*[\n].*' {
1148 modifier invert-match;
1149 }
1150 }
1151 description
1152 "A one-line title.";
1153 }
1154 leaf body {
1155 type string;
1156 mandatory true;
1157 description
1158 "The body of the post.";
1159 }
1160 description
1161 "A list of posts.";
1162 }
1163 }
1165 container favorites {
1166 description
1167 "The member's favorites.";
1168 leaf-list uint8-numbers {
1169 type uint8;
1170 ordered-by user;
1171 description
1172 "The member's favorite uint8 numbers.";
1173 }
1174 leaf-list uint64-numbers {
1175 type uint64;
1176 ordered-by user;
1177 description
1178 "The member's favorite uint64 numbers.";
1179 }
1180 leaf-list int8-numbers {
1181 type int8;
1182 ordered-by user;
1183 description
1184 "The member's favorite int8 numbers.";
1185 }
1186 leaf-list int64-numbers {
1187 type int64;
1188 ordered-by user;
1189 description
1190 "The member's favorite uint64 numbers.";
1191 }
1192 leaf-list decimal64-numbers {
1193 type decimal64 {
1194 fraction-digits 5;
1195 }
1196 ordered-by user;
1197 description
1198 "The member's favorite decimal64 numbers.";
1199 }
1200 leaf-list bits {
1201 type bits {
1202 bit zero {
1203 position 0;
1204 description "zero";
1205 }
1206 bit one {
1207 position 1;
1208 description "one";
1209 }
1210 bit two {
1211 position 2;
1212 description "two";
1213 }
1214 }
1215 ordered-by user;
1216 description
1217 "The member's favorite bits.";
1218 }
1219 }
1221 container stats {
1222 config false;
1223 description
1224 "Operational state members values.";
1225 leaf joined {
1226 type yang:date-and-time;
1227 mandatory true;
1228 description
1229 "Timestamp when member joined.";
1230 }
1231 leaf membership-level {
1232 type enumeration {
1233 enum admin {
1234 description
1235 "Site administrator.";
1236 }
1237 enum standard {
1238 description
1239 "Standard membership level.";
1240 }
1241 enum pro {
1242 description
1243 "Professional membership level.";
1244 }
1245 }
1246 mandatory true;
1247 description
1248 "The membership level for this member.";
1249 }
1250 leaf last-activity {
1251 type yang:date-and-time;
1252 description
1253 "Timestamp of member's last activity.";
1254 }
1255 }
1256 }
1257 }
1259 container audit-logs {
1260 config false;
1261 description
1262 "Audit log configuration";
1263 list audit-log {
1264 description
1265 "List of audit logs.";
1266 leaf timestamp {
1267 type yang:date-and-time;
1268 mandatory true;
1269 description
1270 "The timestamp for the event.";
1271 }
1272 leaf member-id {
1273 type string;
1274 mandatory true;
1275 description
1276 "The 'member-id' of the member.";
1277 }
1278 leaf source-ip {
1279 type inet:ip-address;
1280 mandatory true;
1281 description
1282 "The apparent IP address the member used.";
1283 }
1284 leaf request {
1285 type string;
1286 mandatory true;
1287 description
1288 "The member's request.";
1289 }
1290 leaf outcome {
1291 type boolean;
1292 mandatory true;
1293 description
1294 "Indicate if request was permitted.";
1295 }
1296 }
1297 }
1298 }
1300 A.2. Example Data Set
1302 The examples assume the server's operational state as follows.
1304 The data is provided in JSON only for convenience and, in particular,
1305 has no bearing on the "generic" nature of the tests themselves.
1307 {
1308 "example-social:members": {
1309 "member": [
1310 {
1311 "member-id": "bob",
1312 "email-address": "bob@example.com",
1313 "password": "$0$1543",
1314 "avatar": "BASE64VALUE=",
1315 "tagline": "Here and now, like never before.",
1316 "posts": {
1317 "post": [
1318 {
1319 "timestamp": "2020-08-14T03:32:25Z",
1320 "body": "Just got in."
1321 },
1322 {
1323 "timestamp": "2020-08-14T03:33:55Z",
1324 "body": "What's new?"
1325 },
1326 {
1327 "timestamp": "2020-08-14T03:34:30Z",
1328 "body": "I'm bored..."
1329 }
1330 ]
1331 },
1332 "favorites": {
1333 "decimal64-numbers": ["3.14159", "2.71828"]
1334 },
1335 "stats": {
1336 "joined": "2020-08-14T03:30:00Z",
1337 "membership-level": "standard",
1338 "last-activity": "2020-08-14T03:34:30Z"
1339 }
1340 },
1341 {
1342 "member-id": "eric",
1343 "email-address": "eric@example.com",
1344 "password": "$0$1543",
1345 "avatar": "BASE64VALUE=",
1346 "tagline": "Go to bed with dreams; wake up with a purpose.",
1347 "following": ["alice"],
1348 "posts": {
1349 "post": [
1350 {
1351 "timestamp": "2020-09-17T18:02:04Z",
1352 "title": "Son, brother, husband, father",
1353 "body": "What's your story?"
1354 }
1355 ]
1356 },
1357 "favorites": {
1358 "bits": ["two", "one", "zero"]
1359 },
1360 "stats": {
1361 "joined": "2020-09-17T19:38:32Z",
1362 "membership-level": "pro",
1363 "last-activity": "2020-09-17T18:02:04Z"
1364 }
1365 },
1366 {
1367 "member-id": "alice",
1368 "email-address": "alice@example.com",
1369 "password": "$0$1543",
1370 "avatar": "BASE64VALUE=",
1371 "tagline": "Every day is a new day",
1372 "privacy-settings": {
1373 "hide-network": "false",
1374 "post-visibility": "public"
1375 },
1376 "following": ["bob", "eric", "lin"],
1377 "posts": {
1378 "post": [
1379 {
1380 "timestamp": "2020-07-08T13:12:45Z",
1381 "title": "My first post",
1382 "body": "Hiya all!"
1383 },
1384 {
1385 "timestamp": "2020-07-09T01:32:23Z",
1386 "title": "Sleepy...",
1387 "body": "Catch y'all tomorrow."
1388 }
1389 ]
1390 },
1391 "favorites": {
1392 "uint8-numbers": [17, 13, 11, 7, 5, 3],
1393 "int8-numbers": [-5, -3, -1, 1, 3, 5]
1394 },
1395 "stats": {
1396 "joined": "2020-07-08T12:38:32Z",
1397 "membership-level": "admin",
1398 "last-activity": "2021-04-01T02:51:11Z"
1399 }
1400 },
1401 {
1402 "member-id": "lin",
1403 "email-address": "lin@example.com",
1404 "password": "$0$1543",
1405 "privacy-settings": {
1406 "hide-network": "true",
1407 "post-visibility": "followers-only"
1408 },
1409 "following": ["joe", "eric", "alice"],
1410 "stats": {
1411 "joined": "2020-07-09T12:38:32Z",
1412 "membership-level": "standard",
1413 "last-activity": "2021-04-01T02:51:11Z"
1414 }
1415 },
1416 {
1417 "member-id": "joe",
1418 "email-address": "joe@example.com",
1419 "password": "$0$1543",
1420 "avatar": "BASE64VALUE=",
1421 "tagline": "Greatness is measured by courage and heart.",
1422 "privacy-settings": {
1423 "post-visibility": "unlisted"
1424 },
1425 "following": ["bob"],
1426 "posts": {
1427 "post": [
1428 {
1429 "timestamp": "2020-10-17T18:02:04Z",
1430 "body": "What's your status?"
1431 }
1432 ]
1433 },
1434 "stats": {
1435 "joined": "2020-10-08T12:38:32Z",
1436 "membership-level": "pro",
1437 "last-activity": "2021-04-01T02:51:11Z"
1438 }
1439 }
1440 ]
1441 },
1442 "example-social:audit-logs": {
1443 "audit-log": [
1444 {
1445 "timestamp": "2020-10-11T06:47:59Z",
1446 "member-id": "alice",
1447 "source-ip": "192.168.0.92",
1448 "request": "POST /groups/group/2043",
1449 "outcome": true
1450 },
1451 {
1452 "timestamp": "2020-11-01T15:22:01Z",
1453 "member-id": "bob",
1454 "source-ip": "192.168.2.16",
1455 "request": "POST /groups/group/123",
1456 "outcome": false
1458 },
1459 {
1460 "timestamp": "2020-12-12T21:00:28Z",
1461 "member-id": "eric",
1462 "source-ip": "192.168.254.1",
1463 "request": "POST /groups/group/10",
1464 "outcome": true
1465 },
1466 {
1467 "timestamp": "2021-01-03T06:47:59Z",
1468 "member-id": "alice",
1469 "source-ip": "192.168.0.92",
1470 "request": "POST /groups/group/333",
1471 "outcome": true
1472 },
1473 {
1474 "timestamp": "2021-01-21T10:00:00Z",
1475 "member-id": "bob",
1476 "source-ip": "192.168.2.16",
1477 "request": "POST /groups/group/42",
1478 "outcome": true
1479 },
1480 {
1481 "timestamp": "2020-02-07T09:06:21Z",
1482 "member-id": "alice",
1483 "source-ip": "192.168.0.92",
1484 "request": "POST /groups/group/1202",
1485 "outcome": true
1486 },
1487 {
1488 "timestamp": "2020-02-28T02:48:11Z",
1489 "member-id": "bob",
1490 "source-ip": "192.168.2.16",
1491 "request": "POST /groups/group/345",
1492 "outcome": true
1493 }
1494 ]
1495 }
1496 }
1498 A.3. Example Queries
1500 The following sections are presented in reverse query-parameters
1501 processing order. Starting with the simplest (limit) and ending with
1502 the most complex (where).
1504 All the vector tests are presented in a protocol-independent manner.
1505 JSON is used only for its conciseness.
1507 A.3.1. The "limit" Parameter
1509 Noting that "limit" must be a positive number, the edge condition
1510 values are '1', '2', num-elements-1, num-elements, and num-
1511 elements+1.
1513 | If '0' were a valid limit value, it would always return an
1514 | empty result set. Any value greater than or equal to num-
1515 | elements results the entire result set, same as when "limit" is
1516 | unspecified.
1518 These vector tests assume the target "/example-
1519 social:members/member=alice/favorites/uint8-numbers", which has six
1520 values, thus the edge condition "limit" values are: '1', '2', '5',
1521 '6', and '7'.
1523 A.3.1.1. limit=1
1525 REQUEST
1527 Target: /example-social:members/member=alice/favorites/uint8-numbers
1528 Pagination Parameters:
1529 Where: -
1530 Sort-by: -
1531 Direction: -
1532 Offset: -
1533 Limit: 1
1535 RESPONSE
1537 {
1538 "example-social:uint8-numbers": [17],
1539 "@example-social:uint8-numbers": [
1540 {
1541 "ietf-list-pagination:remaining": 5
1542 }
1543 ]
1544 }
1546 A.3.1.2. limit=2
1548 REQUEST
1549 Target: /example-social:members/member=alice/favorites/uint8-numbers
1550 Pagination Parameters:
1551 Where: -
1552 Sort-by: -
1553 Direction: -
1554 Offset: -
1555 Limit: 2
1557 RESPONSE
1559 {
1560 "example-social:uint8-numbers": [17, 13],
1561 "@example-social:uint8-numbers": [
1562 {
1563 "ietf-list-pagination:remaining": 4
1564 }
1565 ]
1566 }
1568 A.3.1.3. limit=5
1570 REQUEST
1572 Target: /example-social:members/member=alice/favorites/uint8-numbers
1573 Pagination Parameters:
1574 Where: -
1575 Sort-by: -
1576 Direction: -
1577 Offset: -
1578 Limit: 5
1580 RESPONSE
1582 {
1583 "example-social:uint8-numbers": [17, 13, 11, 7, 5],
1584 "@example-social:uint8-numbers": [
1585 {
1586 "ietf-list-pagination:remaining": 1
1587 }
1588 ]
1589 }
1591 A.3.1.4. limit=6
1593 REQUEST
1594 Target: /example-social:members/member=alice/favorites/uint8-numbers
1595 Pagination Parameters:
1596 Where: -
1597 Sort-by: -
1598 Direction: -
1599 Offset: -
1600 Limit: 6
1602 RESPONSE
1604 {
1605 "example-social:uint8-numbers": [17, 13, 11, 7, 5, 3]
1606 }
1608 A.3.1.5. limit=7
1610 REQUEST
1612 Target: /example-social:members/member=alice/favorites/uint8-numbers
1613 Pagination Parameters:
1614 Where: -
1615 Sort-by: -
1616 Direction: -
1617 Offset: -
1618 Limit: 7
1620 RESPONSE
1622 {
1623 "example-social:uint8-numbers": [17, 13, 11, 7, 5, 3]
1624 }
1626 A.3.2. The "offset" Parameter
1628 Noting that "offset" must be an unsigned number less than or equal to
1629 the num-elements, the edge condition values are '0', '1', '2', num-
1630 elements-1, num-elements, and num-elements+1.
1632 These vector tests again assume the target "/example-
1633 social:members/member=alice/favorites/uint8-numbers", which has six
1634 values, thus the edge condition "limit" values are: '0', '1', '2',
1635 '5', '6', and '7'.
1637 A.3.2.1. offset=0
1639 REQUEST
1640 Target: /example-social:members/member=alice/favorites/uint8-numbers
1641 Pagination Parameters:
1642 Where: -
1643 Sort-by: -
1644 Direction: -
1645 Offset: 0
1646 Limit: -
1648 RESPONSE
1650 {
1651 "example-social:uint8-numbers": [17, 13, 11, 7, 5, 3]
1652 }
1654 A.3.2.2. offset=1
1656 REQUEST
1658 Target: /example-social:members/member=alice/favorites/uint8-numbers
1659 Pagination Parameters:
1660 Where: -
1661 Sort-by: -
1662 Direction: -
1663 Offset: 1
1664 Limit: -
1666 RESPONSE
1668 {
1669 "example-social:uint8-numbers": [13, 11, 7, 5, 3]
1670 }
1672 A.3.2.3. offset=2
1674 REQUEST
1676 Target: /example-social:members/member=alice/favorites/uint8-numbers
1677 Pagination Parameters:
1678 Where: -
1679 Sort-by: -
1680 Direction: -
1681 Offset: 2
1682 Limit: -
1684 RESPONSE
1685 {
1686 "example-social:uint8-numbers": [11, 7, 5, 3]
1687 }
1689 A.3.2.4. offset=5
1691 REQUEST
1693 Target: /example-social:members/member=alice/favorites/uint8-numbers
1694 Pagination Parameters:
1695 Where: -
1696 Sort-by: -
1697 Direction: -
1698 Offset: 5
1699 Limit: -
1701 RESPONSE
1703 {
1704 "example-social:uint8-numbers": [3]
1705 }
1707 A.3.2.5. offset=6
1709 REQUEST
1711 Target: /example-social:members/member=alice/favorites/uint8-numbers
1712 Pagination Parameters:
1713 Where: -
1714 Sort-by: -
1715 Direction: -
1716 Offset: 6
1717 Limit: -
1719 RESPONSE
1721 {
1722 "example-social:uint8-numbers": []
1723 }
1725 A.3.2.6. offset=7
1727 REQUEST
1728 Target: /example-social:members/member=alice/favorites/uint8-numbers
1729 Pagination Parameters:
1730 Where: -
1731 Sort-by: -
1732 Direction: -
1733 Offset: 7
1734 Limit: -
1736 RESPONSE
1738 ERROR
1740 A.3.3. The "direction" Parameter
1742 Noting that "direction" is an enumeration with two values, the edge
1743 condition values are each defined enumeration.
1745 | The value "forwards" is sometimes known as the "default" value,
1746 | as it produces the same result set as when "direction" is
1747 | unspecified.
1749 These vector tests again assume the target "/example-
1750 social:members/member=alice/favorites/uint8-numbers". The number of
1751 elements is relevant to the edge condition values.
1753 | It is notable that "uint8-numbers" is an "ordered-by" user
1754 | leaf-list. Traversals are over the user-specified order, not
1755 | the numerically-sorted order, which is what the "sort-by"
1756 | parameter addresses. If this were an "ordered-by system" leaf-
1757 | list, then the traversals would be over the system-specified
1758 | order, again not a numerically-sorted order.
1760 A.3.3.1. direction=forwards
1762 REQUEST
1764 Target: /example-social:members/member=alice/favorites/uint8-numbers
1765 Pagination Parameters:
1766 Where: -
1767 Sort-by: -
1768 Direction: forwards
1769 Offset: -
1770 Limit: -
1772 RESPONSE
1773 {
1774 "example-social:uint8-numbers": [17, 13, 11, 7, 5, 3]
1775 }
1777 A.3.3.2. direction=backwards
1779 REQUEST
1781 Target: /example-social:members/member=alice/favorites/uint8-numbers
1782 Pagination Parameters:
1783 Where: -
1784 Sort-by: -
1785 Direction: backwards
1786 Offset: -
1787 Limit: -
1789 RESPONSE
1791 {
1792 "example-social:uint8-numbers": [3, 5, 7, 11, 13, 17]
1793 }
1795 A.3.4. The "sort-by" Parameter
1797 Noting that the "sort-by" parameter is a node identifier, there is
1798 not so much "edge conditions" as there are "interesting conditions".
1799 This section provides examples for some interesting conditions.
1801 A.3.4.1. the target node's type
1803 The section provides three examples, one for a "leaf-list" and two
1804 for a "list", with one using a direct descendent and the other using
1805 an indirect descendent.
1807 A.3.4.1.1. type is a "leaf-list"
1809 This example illustrates when the target node's type is a "leaf-
1810 list". Note that a single period (i.e., '.') is used to represent
1811 the nodes to be sorted.
1813 This test again uses the target "/example-
1814 social:members/member=alice/favorites/uint8-numbers", which is a
1815 leaf-list.
1817 REQUEST
1818 Target: /example-social:members/member=alice/favorites/uint8-numbers
1819 Pagination Parameters:
1820 Where: -
1821 Sort-by: .
1822 Direction: -
1823 Offset: -
1824 Limit: -
1826 RESPONSE
1828 {
1829 "example-social:uint8-numbers": [3, 5, 7, 11, 13, 17]
1830 }
1832 A.3.4.1.2. type is a "list" and sort-by node is a direct descendent
1834 This example illustrates when the target node's type is a "list" and
1835 a direct descendent is the "sort-by" node.
1837 This vector test uses the target "/example-social:members/member",
1838 which is a "list", and the sort-by descendent node "member-id", which
1839 is the "key" for the list.
1841 REQUEST
1843 Target: /example-social:members/member
1844 Pagination Parameters:
1845 Where: -
1846 Sort-by: member-id
1847 Direction: -
1848 Offset: -
1849 Limit: -
1851 RESPONSE
1853 | To make the example more understandable, an ellipse (i.e.,
1854 | "...") is used to represent a missing subtree of data.
1856 {
1857 "example-social:member": [
1858 {
1859 "member-id": "alice",
1860 ...
1861 },
1862 {
1863 "member-id": "bob",
1864 ...
1865 },
1866 {
1867 "member-id": "eric",
1868 ...
1869 },
1870 {
1871 "member-id": "joe",
1872 ...
1873 },
1874 {
1875 "member-id": "lin",
1876 ...
1877 }
1878 ]
1879 }
1881 A.3.4.1.3. type is a "list" and sort-by node is an indirect descendent
1883 This example illustrates when the target node's type is a "list" and
1884 an indirect descendent is the "sort-by" node.
1886 This vector test uses the target "/example-social:members/member",
1887 which is a "list", and the sort-by descendent node "stats/joined",
1888 which is a "config false" descendent leaf. Due to "joined" being a
1889 "config false" node, this request would have to target the "member"
1890 node in the datastore.
1892 REQUEST
1894 Target: /example-social:members/member
1895 Pagination Parameters:
1896 Where: -
1897 Sort-by: stats/joined
1898 Direction: -
1899 Offset: -
1900 Limit: -
1902 RESPONSE
1903 | To make the example more understandable, an elipse (i.e.,
1904 | "...") is used to represent a missing subtree of data.
1906 {
1907 "example-social:member": [
1908 {
1909 "member-id": "alice",
1910 ...
1911 },
1912 {
1913 "member-id": "lin",
1914 ...
1915 },
1916 {
1917 "member-id": "bob",
1918 ...
1919 },
1920 {
1921 "member-id": "eric",
1922 ...
1923 },
1924 {
1925 "member-id": "joe",
1926 ...
1927 }
1928 ]
1929 }
1931 A.3.4.2. handling missing entries
1933 The section provides one example for when the "sort-by" node is not
1934 present in the data set.
1936 FIXME: need to finish this section...
1938 A.3.5. The "where" Parameter
1940 The "where" is an XPath 1.0 expression, there are numerous edge
1941 conditions to consider, e.g., the types of the nodes that are
1942 targeted by the expression.
1944 A.3.5.1. match of leaf-list's values
1946 FIXME
1948 A.3.5.2. match on descendent string containing a substring
1950 This example selects members that have an email address containing
1951 "@example.com".
1953 REQUEST
1955 Target: /example-social:members/member
1956 Pagination Parameters:
1957 Where: //.[contains (@email-address,'@example.com')]
1958 Sort-by: -
1959 Direction: -
1960 Offset: -
1961 Limit: -
1963 RESPONSE
1965 | To make the example more understandable, an elipse (i.e.,
1966 | "...") is used to represent a missing subtree of data.
1968 {
1969 "example-social:member": [
1970 {
1971 "member-id": "bob",
1972 ...
1973 },
1974 {
1975 "member-id": "eric",
1976 ...
1977 },
1978 {
1979 "member-id": "alice",
1980 ...
1981 },
1982 {
1983 "member-id": "joe",
1984 ...
1985 },
1986 {
1987 "member-id": "lin",
1988 ...
1989 }
1990 ]
1991 }
1993 A.3.5.3. match on decendent timestamp starting with a substring
1995 This example selects members that have a posting whose timestamp
1996 begins with the string "2020".
1998 REQUEST
2000 Target: /example-social:members/member
2001 Pagination Parameters:
2002 Where: //posts//post[starts-with(@timestamp,'2020')]
2003 Sort-by: -
2004 Direction: -
2005 Offset: -
2006 Limit: -
2008 RESPONSE
2010 | To make the example more understandable, an elipse (i.e.,
2011 | "...") is used to represent a missing subtree of data.
2013 {
2014 "example-social:member": [
2015 {
2016 "member-id": "bob",
2017 ...
2018 },
2019 {
2020 "member-id": "eric",
2021 ...
2022 },
2023 {
2024 "member-id": "alice",
2025 ...
2026 },
2027 {
2028 "member-id": "joe",
2029 ...
2030 }
2031 ]
2032 }
2034 A.3.6. The "sublist-limit" Parameter
2036 The "sublist-limit" parameter may be used on any target node.
2038 A.3.6.1. target is a list entry
2040 This example uses the target node '/example-social:members/
2041 member=alice' in the datastore.
2043 | The target node is a specific list entry/element node, not the
2044 | YANG "list" node.
2046 This example sets the sublist-limit value '1', which returns just the
2047 first entry for all descendent lists and leaf-lists.
2049 Note that, in the response, the "remaining" metadata value is set on
2050 the first element of each descendent list and leaf-list having more
2051 than one value.
2053 REQUEST
2055 Datastore:
2056 Target: /example-social:members/member=alice
2057 Sublist-limit: 1
2058 Pagination Parameters:
2059 Where: -
2060 Sort-by: -
2061 Direction: -
2062 Offset: -
2063 Limit: -
2065 RESPONSE
2066 {
2067 "example-social:member": [
2068 {
2069 "member-id": "alice",
2070 "email-address": "alice@example.com",
2071 "password": "$0$1543",
2072 "avatar": "BASE64VALUE=",
2073 "tagline": "Every day is a new day",
2074 "privacy-settings": {
2075 "hide-network": "false",
2076 "post-visibility": "public"
2077 },
2078 "following": ["bob"],
2079 "@following": [
2080 {
2081 "ietf-list-pagination:remaining": "2"
2082 }
2083 ],
2084 "posts": {
2085 "post": [
2086 {
2087 "@": {
2088 "ietf-list-pagination:remaining": "1"
2089 },
2090 "timestamp": "2020-07-08T13:12:45Z",
2091 "title": "My first post",
2092 "body": "Hiya all!"
2093 }
2094 ]
2095 },
2096 "favorites": {
2097 "uint8-numbers": [17],
2098 "int8-numbers": [-5],
2099 "@uint8-numbers": [
2100 {
2101 "ietf-list-pagination:remaining": "5"
2102 }
2103 ],
2104 "@int8-numbers": [
2105 {
2106 "ietf-list-pagination:remaining": "5"
2107 }
2108 ]
2109 }
2110 }
2111 ]
2112 }
2114 A.3.6.2. target is a datastore
2116 This example uses the target node .
2118 This example sets the sublist-limit value '1', which returns just the
2119 first entry for all descendent lists and leaf-lists.
2121 Note that, in the response, the "remaining" metadata value is set on
2122 the first element of each descendent list and leaf-list having more
2123 than one value.
2125 REQUEST
2127 Datastore:
2128 Target: /
2129 Sublist-limit: 1
2130 Pagination Parameters:
2131 Where: -
2132 Sort-by: -
2133 Direction: -
2134 Offset: -
2135 Limit: -
2137 RESPONSE
2138 {
2139 "example-social:members": {
2140 "member": [
2141 {
2142 "@": {
2143 "ietf-list-pagination:remaining": "4"
2144 },
2145 "member-id": "bob",
2146 "email-address": "bob@example.com",
2147 "password": "$0$1543",
2148 "avatar": "BASE64VALUE=",
2149 "tagline": "Here and now, like never before.",
2150 "posts": {
2151 "post": [
2152 {
2153 "@": {
2154 "ietf-list-pagination:remaining": "2"
2155 },
2156 "timestamp": "2020-08-14T03:32:25Z",
2157 "body": "Just got in."
2158 }
2159 ]
2160 },
2161 "favorites": {
2162 "decimal64-numbers": ["3.14159"],
2163 "@decimal64-numbers": [
2164 {
2165 "ietf-list-pagination:remaining": "1"
2166 }
2167 ]
2168 }
2169 }
2170 ]
2171 }
2172 }
2174 A.3.7. Combinations of Parameters
2176 A.3.7.1. All six parameters at once
2178 REQUEST
2179 Datastore:
2180 Target: /example-social:members/member
2181 Sublist-limit: 1
2182 Pagination Parameters:
2183 Where: //stats//joined[starts-with(@timestamp,'2020')]
2184 Sort-by: member-id
2185 Direction: backwards
2186 Offset: 2
2187 Limit: 2
2189 RESPONSE
2191 {
2192 "example-social:member": [
2193 {
2194 "@": {
2195 "ietf-list-pagination:remaining": "1"
2196 },
2197 "member-id": "eric",
2198 "email-address": "eric@example.com",
2199 "password": "$0$1543",
2200 "avatar": "BASE64VALUE=",
2201 "tagline": "Go to bed with dreams; wake up with a purpose.",
2202 "following": ["alice"],
2203 "posts": {
2204 "post": [
2205 {
2206 "timestamp": "2020-09-17T18:02:04Z",
2207 "title": "Son, brother, husband, father",
2208 "body": "What's your story?"
2209 }
2210 ]
2211 },
2212 "favorites": {
2213 "bits": ["two"],
2214 "@bits": [
2215 {
2216 "ietf-list-pagination:remaining": "2"
2217 }
2218 ]
2219 },
2220 "stats": {
2221 "joined": "2020-09-17T19:38:32Z",
2222 "membership-level": "pro",
2223 "last-activity": "2020-09-17T18:02:04Z"
2224 }
2225 },
2226 {
2227 "member-id": "bob",
2228 "email-address": "bob@example.com",
2229 "password": "$0$1543",
2230 "avatar": "BASE64VALUE=",
2231 "tagline": "Here and now, like never before.",
2232 "posts": {
2233 "post": [
2234 {
2235 "@": {
2236 "ietf-list-pagination:remaining": "2"
2237 },
2238 "timestamp": "2020-08-14T03:32:25Z",
2239 "body": "Just got in."
2240 }
2241 ]
2242 },
2243 "favorites": {
2244 "decimal64-numbers": ["3.14159"],
2245 "@decimal64-numbers": [
2246 {
2247 "ietf-list-pagination:remaining": "1"
2248 }
2249 ]
2250 },
2251 "stats": {
2252 "joined": "2020-08-14T03:30:00Z",
2253 "membership-level": "standard",
2254 "last-activity": "2020-08-14T03:34:30Z"
2255 }
2256 }
2257 }
2258 }
2260 Acknowledgements
2262 The authors would like to thank the following for lively discussions
2263 on list (ordered by first name): Andy Bierman, Martin Bjoerklund, and
2264 Robert Varga.
2266 Authors' Addresses
2268 Kent Watsen
2269 Watsen Networks
2271 Email: kent+ietf@watsen.net
2272 Qin Wu
2273 Huawei Technologies
2275 Email: bill.wu@huawei.com
2277 Olof Hagsand
2278 Netgate
2280 Email: olof@hagsand.se
2282 Hongwei Li
2283 Hewlett Packard Enterprise
2285 Email: flycoolman@gmail.com
2287 Per Andersson
2288 Cisco Systems
2290 Email: perander@cisco.com