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