idnits 2.17.1 draft-yang-json-rpc-03.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 : ---------------------------------------------------------------------------- ** The document seems to lack a Security Considerations section. ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) == There are 1 instance of lines with non-RFC2606-compliant FQDNs in the document. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (August 13, 2018) is 2082 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- ** Obsolete normative reference: RFC 7159 (Obsoleted by RFC 8259) ** Obsolete normative reference: RFC 7230 (Obsoleted by RFC 9110, RFC 9112) Summary: 4 errors (**), 0 flaws (~~), 2 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group A. Ivanov 3 Internet-Draft D. Spence 4 Intended status: Informational S. Saxena 5 Expires: February 14, 2019 T. Nadeau 6 Brocade 7 August 13, 2018 9 Application of YANG Modeling to JSON RPCs for Interoperability Purposes 10 draft-yang-json-rpc-03 12 Abstract 14 This document specifies the application of YANG modeling language to 15 JSON RPC 2.0 for the purposes of achieving interoperability between 16 implementations. 18 Status of This Memo 20 This Internet-Draft is submitted in full conformance with the 21 provisions of BCP 78 and BCP 79. 23 Internet-Drafts are working documents of the Internet Engineering 24 Task Force (IETF). Note that other groups may also distribute 25 working documents as Internet-Drafts. The list of current Internet- 26 Drafts is at https://datatracker.ietf.org/drafts/current/. 28 Internet-Drafts are draft documents valid for a maximum of six months 29 and may be updated, replaced, or obsoleted by other documents at any 30 time. It is inappropriate to use Internet-Drafts as reference 31 material or to cite them other than as "work in progress." 33 This Internet-Draft will expire on February 14, 2019. 35 Copyright Notice 37 Copyright (c) 2018 IETF Trust and the persons identified as the 38 document authors. All rights reserved. 40 This document is subject to BCP 78 and the IETF Trust's Legal 41 Provisions Relating to IETF Documents 42 (https://trustee.ietf.org/license-info) in effect on the date of 43 publication of this document. Please review these documents 44 carefully, as they describe your rights and restrictions with respect 45 to this document. Code Components extracted from this document must 46 include Simplified BSD License text as described in Section 4.e of 47 the Trust Legal Provisions and are provided without warranty as 48 described in the Simplified BSD License. 50 Table of Contents 52 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 53 2. Terminology and Notation . . . . . . . . . . . . . . . . . . 3 54 3. Modeling of JSON RPC 2.0 Interfaces in YANG . . . . . . . . . 3 55 3.1. Optionality . . . . . . . . . . . . . . . . . . . . . . . . 5 56 3.2. Default values . . . . . . . . . . . . . . . . . . . . . . 7 57 3.3. The idl:value-type YANG Extension . . . . . . . . . . . . . 8 58 3.4. Modeling of JSON RPC 2.0 RPCs . . . . . . . . . . . . . . . 9 59 3.4.1. Representing results . . . . . . . . . . . . . . . . . . 9 60 3.4.2. Modeling and expressing in JSON of data structures fully 61 described by model . . . . . . . . . . . . . . . . . . . 10 62 3.4.3. Modeling and expressing in JSON of data structures with 63 elements outside model scope . . . . . . . . . . . . . . 12 64 3.5. Modeling of JSON RPC 2.0 Notifications . . . . . . . . . . 15 65 3.5.1. Modeling and expressing in JSON of notifications with 66 fully modeled data payload . . . . . . . . . . . . . . . 15 67 3.5.2. Modeling and expressing in JSON of notifications with 68 data payload outside model scope . . . . . . . . . . . . 16 69 3.6. Addressing Modeled Data - Yang Paths . . . . . . . . . . . 17 70 3.6.1. Addressing anything but an individual list element . . . 18 71 3.6.2. Addressing an individual list element . . . . . . . . . . 18 72 3.6.3. Addressing inside an individual list element . . . . . . 18 73 4. Normative References . . . . . . . . . . . . . . . . . . . . 19 74 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 76 1. Introduction 78 A key use case for JSON encoding of data is the transfer and 79 interchange of such data between applications. While some of the 80 semantics desribed here will be of value for any such interchange, 81 this document will concentrate on two specific use cases - Remote 82 Procedure Calls (RPCs) and Notifications. There is a standard 83 specification for using JSON in both - it is the JSON RPC 2.0 84 specification maintained by JSON RPC working group at jsonrpc.org 85 [JSONRPC20]. This specification uses JSON as described in [RFC7159] 86 in messages transported over a variety of transports. For example - 87 HTTP [RFC7230], 0MQ [ZEROMQ], AMQP [AMQP] etc. 89 The JSON RPC 2.0 specification [JSONRPC20] has a number of well known 90 shortcomings. There are no means of describing and documenting a 91 particular API method. There are no means to specify how to 92 interpret data received via an RPC call or notification and what data 93 structures should be generated to accommodate the data. Most 94 implementers have concentrated on the loss of data structure 95 information as a key deficiency, while ignoring the lack of API 96 description which is the actual root cause. This has led them to 97 encode information about the data structures into bespoke extensions 98 also known as class hints and/or use of special "magic" method 99 notations as implemented in [JABSORB], [PJ0MQ], etc. These break the 100 core assumption of JSON being a language agnostic interchange format 101 and result in a plethora of subtly incompatible JSON RPC 102 implementations. 104 This document proposes an alternative to class hints and other non- 105 interoperable extensions through the use of "JSON Encoding of Data 106 Modeled with YANG" RFC [RFC7951] and YANG modeling of JSON RPCs. 108 2. Terminology and Notation 110 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 111 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 112 document are to be interpreted as described in [RFC2119]. 114 YANG is the data modeling language as described in [RFC7950], version 115 1.1 117 JSON encoding of YANG modeled data structures is described in 118 [RFC7951] 120 JSON RPC 2.0 is the Remote Procedure Call and Notifications encoding 121 as described in [JSONRPC20] 123 3. Modeling of JSON RPC 2.0 Interfaces in YANG 125 All RPCs in a particular API must be described as RPC statements in 126 its corresponding YANG model in accordance to the rules of RFC7950 127 [RFC7950], section 7.14, which is expanded to cover JSON RPCs in 128 addition to NETCONF RPCs. The RPC arguments and results must comply 129 to subsections 7.14.2 and 7.14.3 of RFC7950 [RFC7950]. 131 All Notifications provided by a particular API must be described as 132 notification statements in its corresponding YANG model in accordance 133 to the rules of RFC7950 [RFC7950], section 7.15 which is expanded to 134 cover JSON Notifications in addition to NETCONF ones. The JSON 135 Notification payload and substatements must comply to subsection 136 7.15.1 of RFC7950 [RFC7950]. 138 While all applicable YANG statements as specified by RFC7950 139 [RFC7950] are supported and acceptable in both RPCs and 140 notifications, the use of must, when, leafref and identityref is 141 discouraged to improve interoperability with implementations which 142 use simplistic serialization/deserialization to parse the messages 143 and do not have a fully featured YANG interpreter. The internal 144 mapping of an RPC name to a function call is an implementation detail 145 outside the scope of this document. RPC method names containing 146 characters invalid as a part of a function name in most computing 147 languages are discouraged, but not prohibited. 149 All mappings from application data types to JSON representation types 150 MUST use the conventions defined in "JSON Encoding of Data Modeled 151 with YANG" [RFC7951]. The JSON message payload must use the I-JSON 152 profile according to [RFC7493]. 154 If an application does not wish to specify the model constraints for 155 a particular RPC argument or Notification payload it must specify the 156 corresponding element as anydata in the YANG model. 158 JSON RPC Specification [JSONRPC20] mandates that positional arguments 159 are always represented as a list even if an RPC call or Notification 160 has a single argument. 162 For example, if an RPC is modelled as: 164 grouping arg-uri { 165 leaf uri { 166 description "A test URI."; 167 mandatory true; 168 type inet:uri; 169 } 170 } 171 rpc test-uri { 172 description "A simple example RPC."; 173 input { 174 uses arg-uri; 175 } 176 } 178 Figure 1 180 The following payload is invalid - it violates the JSON RPC 181 Specification [JSONRPC20]: 183 { 184 "jsonrpc": "2.0", 185 "id": 3, 186 "method": "test-uri", 187 "params": "http://www.ietf.org" 188 } 190 Figure 2 192 The correct parameter encoding is as follows: 194 { 195 "jsonrpc": "2.0", 196 "id": 3, 197 "method": "test-uri", 198 "params": [ 199 "http://www.ietf.org" 200 ] 201 } 203 Figure 3 205 or 207 { 208 "jsonrpc": "2.0", 209 "id": 3, 210 "method": "test-uri", 211 "params": { 212 "uri": "http://www.ietf.org" 213 } 214 } 216 Figure 4 218 YANG models describing different RPCs and Notifications may be 219 grouped together into a YANG module to describe an API or a set of 220 APIs. 222 3.1. Optionality 224 Omitted optional parameters for the positional form of JSON RPC 2.0 225 [JSONRPC20] must be specified as null elements in the argument array. 227 For example, both arguments in the test-elements RPC are optional. 229 rpc test-elements { 230 description "A simple example RPC."; 231 input { 232 leaf element1 { 233 type string; 234 } 235 leaf element2 { 236 type string; 237 } 238 } 239 } 241 Figure 5 243 If only element2 is supplied, the resulting JSON RPC payload using 244 the positional form should be: 246 { 247 "id": 3, 248 "jsonrpc": "2.0", 249 "method": "test-elements", 250 "params": [ 251 null, 252 "element2 value" 253 ] 254 } 256 Figure 6 258 The named form should be: 260 { 261 "jsonrpc":"2.0", 262 "id":3, 263 "method":"test-elements", 264 "params":{ 265 "element2": "element2 value" 266 } 267 } 269 Figure 7 271 While using the named form can allow an implementation to 272 differentiate between a parameter being supplied and a parameter 273 being null, implementers should not rely on this difference in 274 semantics as most computing language compilers and runtimes will 275 obscure this difference from the caller. 277 Trailing nulls resulting from missing parameters or an implementation 278 supplying a null argument MAY be stripped from a call by position 279 payload. The following encoding: 281 { 282 "jsonrpc": "2.0", 283 "id": 3, 284 "method": "test-elements", 285 "params": [ 286 "element1 value", 287 null 288 ] 289 } 291 Figure 8 293 can also be expressed as: 295 { 296 "jsonrpc": "2.0", 297 "id": 3, 298 "method": "test-elements", 299 "params": [ 300 "element1 value" 301 ] 302 } 304 Figure 9 306 3.2. Default values 308 The receiving implementation MUST supply any default values as 309 specified by the model if the sender has omitted them as described in 310 RFC7950 [RFC7950], section 7.14.2 and 7.14.3. Thus, in a JSON RPC 311 the caller may omit supplying a default value. The callee (the 312 server) implementation is obliged to fill it in prior to passing the 313 data to an application. For example, for the following model: 315 rpc test-htg-2 { 316 description "A simple example RPC."; 317 input { 318 leaf question { 319 type string; 320 default "Meaning of the Universe"; 321 } 322 } 323 output { 324 leaf answer { 325 type int; 326 default 42; 327 } 328 } 330 Figure 10 332 The test-htg RPC can be invoked with the following payload: 334 { 335 "jsonrpc": "2.0", 336 "id": 3, 337 "method": "test-htg-2", 338 "params": [] 339 } 341 Figure 11 343 The receiver implementation MUST fill the value of "Meaning of the 344 Universe" before passing the parsed payload to the application. The 345 application is not obliged to supply the answer of 42. If the 346 application does not supply an answer, the model aware JSON RPC2.0 347 implementation must add it to the payload prior to it being sent to 348 the caller as an RPC result. 350 3.3. The idl:value-type YANG Extension 352 This document standardizes a new YANG extension idl:value-type 353 compliant to [RFC7950]. This extension specifies additional metadata 354 necessary for a source code generator to produce the correct source 355 code mapping for a specific YANG type. The value provided by the 356 idl:value-type extension is a type hint for the generator and may 357 refine or override the standard type mapping rules specified in "JSON 358 Encoding of Data Modeled with YANG" [RFC7951]. For example: 360 idl:value-type python { 361 idl:implemented-by bsct.enforce.value.TypeBoolean; 362 } 364 Figure 12 366 3.4. Modeling of JSON RPC 2.0 RPCs 368 3.4.1. Representing results 370 In order to simplify integration to existing codebase, RPC calls 371 returning a single result MUST emit a single value for the params key 372 in the RPC message instead of a an array consisting of a one element 373 for the positional form of JSON RPC 2.0 for the cases where it is 374 non-ambiguous, namely lists, leaf-lists and all primitive types. 376 For example, invoking the test-1 RPC in the following example 378 rpc test-1 { 379 description "A simple example RPC."; 380 output { 381 leaf answer { 382 type int; 383 } 384 } 386 Figure 13 388 will produce a simplified result: 390 { 391 "id": 3, 392 "jsonrpc": "2.0", 393 "result": 42 394 } 396 Figure 14 398 This simplification is ambiguous for anydata and container result 399 types. If an RPC call uses the positional form to represent a 400 container or anydata return value, it MUST represent it as an array 401 with a single element equal to the result value. 403 For example, invoking the test-2 RPC in the following example 404 rpc test-2 { 405 description "A simple example RPC."; 406 output { 407 leaf answer { 408 type anydata; 409 } 410 } 412 Figure 15 414 will produce a verbose result: 416 { 417 "id": 3, 418 "jsonrpc": "2.0", 419 "result": [ 420 {"key":"value"} 421 ] 422 } 424 Figure 16 426 3.4.2. Modeling and expressing in JSON of data structures fully 427 described by model 429 All data structures for which the model is known should be fully 430 described in YANG as specified in [RFC7950]. The test-uri RPC in the 431 following example is expecting a uri argument. The uri argument is 432 fully described and modeled: 434 grouping arg-uri { 435 leaf uri { 436 description "A test URI."; 437 mandatory true; 438 type inet:uri; 439 } 440 } 441 rpc test-uri { 442 description "A simple example RPC."; 443 input { 444 uses arg-uri; 445 } 446 output { 447 leaf passes { 448 type boolean; 449 } 450 } 451 } 453 Figure 17 455 The output is a boolean signifying if the test has passed or has 456 failed. For a URI value of "http://www.ietf.org", this corresponds 457 to the following JSON RPC request payload when using positional 458 arguments: 460 { 461 "jsonrpc": "2.0", 462 "id": 3, 463 "method": "test-uri", 464 "params": ["http://www.ietf.org"] 465 } 467 Figure 18 469 Alternatively, when using named arguments 471 { 472 "jsonrpc": "2.0", 473 "id": 3, 474 "method": "test-uri", 475 "params": { 476 "uri": "http://www.ietf.org" 477 } 478 } 480 Figure 19 482 If we assume that the remote procedure call with an argument of 483 "http://www.ietf.org" returns True, we will have the following 484 result. Positional form: 486 { 487 "jsonrpc": "2.0", 488 "id": 3, 489 "result": true 490 } 492 Figure 20 494 Named form: 496 { 497 "jsonrpc": "2.0", 498 "id": 3, 499 "result": { 500 "passes": true 501 } 502 } 504 Figure 21 506 3.4.3. Modeling and expressing in JSON of data structures with elements 507 outside model scope 509 Structures which the implementer does not wish to model in YANG (from 510 here on referred to as "opaque") are specified as anydata. For 511 example the test-object RPC expects an object argument and returns an 512 object output. The argument and the return are opaque to the model 513 and may contain nested structures or structures which the implementer 514 has decided to keep outside the scope of the model. 516 grouping arg-object { 517 leaf object { 518 description "A test Object."; 519 mandatory true; 520 type anydata; 521 } 522 } 523 rpc test-object { 524 description "A simple example RPC."; 525 input { 526 uses arg-object; 527 } 528 output { 529 uses arg-object; 530 } 531 } 533 Figure 22 535 Objects opaque to the model as in this example are encoded as JSON 536 using the rules for anydata in [RFC7951] 538 For an object value of {"key":"value"}, this corresponds to the 539 following JSON RPC request payload when using positional arguments: 541 { 542 "jsonrpc": "2.0", 543 "id": 3, 544 "method": "test-object", 545 "params":[ 546 {"key": "value"} 547 ] 548 } 550 Figure 23 552 Alternatively, when using named arguments 553 { 554 "jsonrpc": "2.0", 555 "id": 3, 556 "method": "test-object", 557 "params": { 558 "object":{ 559 "key": "value" 560 } 561 } 562 } 564 Figure 24 566 If we assume that the procedure call returns the following test- 567 object ["eeny", "meeny", "miny", "moe"], we will have the following 568 result. Positional form: 570 { 571 "jsonrpc": "2.0", 572 "id": 3, 573 "result": [ 574 "eeny", 575 "meeny", 576 "miny", 577 "moe" 578 ] 579 } 581 Figure 25 583 Named form: 585 { 586 "jsonrpc": "2.0", 587 "id": 3, 588 "result": { 589 "object": [ 590 "eeny", 591 "meeny", 592 "miny", 593 "moe" 594 ] 595 } 596 } 598 Figure 26 600 3.5. Modeling of JSON RPC 2.0 Notifications 602 3.5.1. Modeling and expressing in JSON of notifications with fully 603 modeled data payload 605 All data structures for which the model is known should be fully 606 described in YANG as specified in [RFC7950]. The testing 607 Notification in the following example contains a uri leaf. The 608 notification server issuing the notification is expected to supply 609 the value and the recipients will expect the value for this leaf: 611 grouping arg-uri { 612 leaf uri { 613 description "A test URI."; 614 mandatory true; 615 type inet:uri; 616 } 617 } 618 notification notify-uri { 619 description "A simple notification with URI payload."; 620 uses arg-uri; 621 } 623 Figure 27 625 This results in the following notification payloads. Positional 626 arguments: 628 { 629 "jsonrpc": "2.0", 630 "method": "notify-uri", 631 "params": [ 632 "http://www.ietf.org" 633 ] 634 } 636 Figure 28 638 Note - there is no id member in a notification. Alternatively, when 639 using named arguments 640 { 641 "jsonrpc":"2.0", 642 "method": "notify-uri", 643 "params": { 644 "uri": "http://www.ietf.org" 645 } 646 } 648 Figure 29 650 3.5.2. Modeling and expressing in JSON of notifications with data 651 payload outside model scope 653 Structures which the implementer does not wish to model in YANG and 654 pass as object are specified as anydata. For example the notify- 655 object notification expects an object argument as its object leaf. 657 grouping arg-object { 658 leaf object { 659 description "A test Object."; 660 mandatory true; 661 type anydata; 662 } 663 } 664 notification notify-object { 665 description "A simple Notification with an 666 opaque object payload."; 667 uses arg-object; 668 } 670 Figure 30 672 Objects opaque to the model as in this example are encoded as JSON 673 using the rules for anydata in [RFC7951] resulting in the following 674 example payloads for the {"key":"value"} object payload: 676 { 677 "jsonrpc": "2.0", 678 "method": "notify-object", 679 "params": [ 680 { 681 "key": "value" 682 } 683 ] 684 } 686 Figure 31 688 Note - there is no id member in a notification. Alternatively, when 689 using named arguments 691 { 692 "jsonrpc": "2.0", 693 "method": "notify-object", 694 "params": { 695 "object": { 696 "key": "value" 697 } 698 } 699 } 701 Figure 32 703 3.6. Addressing Modeled Data - Yang Paths 705 When working with structured data in a tree form it is essential to 706 be able to address parts of the tree and individual elements. Yang 707 uses Instance Identifiers for this purpose. The current normative 708 reference for this is section 6.1. of [RFC7951]. It borrows the 709 representation from Netconf and represents IIds as an uri path. 710 There are issues with this encoding when used in a JSON RPC context: 712 o Yang IId is intended only for the purposes of addressing data. It 713 does not provide semantics to address RPCs and/or Notifications 714 and their argument which are the primary target of this 715 specification. 717 o The representation in section 6.11 of [RFC7951] does not match 718 JSON semantics - it uses URI syntax which requires conversion for 719 each addressing operation. This approach has some advantages for 720 implementations which support netconf and/or XML in parallel with 721 JSON as these have existing URI parsers. It is, however, clearly 722 disadvantageous for any non-netconf implementation, because it 723 introduces a single "foreign" object type with a non-JSON 724 serialization in the middle of a JSON specification. 726 The path specification specified in this draft provides a 727 representation of paths to address Notification and RPC objects as 728 well as paths into data structures. It MUST be explicitly specified 729 as an anydata object in any models and is not a 1:1 replacement 730 representation for an IId. 732 3.6.1. Addressing anything but an individual list element 734 Containers, leaves, leaf-lists, lists as a whole (everything but an 735 individual element in a list) have their Path expressed as: 737 { 738 "module:top-level-container": { 739 "subcontainer":{} 740 } 741 } 743 Figure 33 745 The path is represented as a single branch tree structure containing 746 nested JSON objects. Each level key is the QName. Path terminates 747 in {} to signify what is being addressed. 749 Module, revision and namespace qualifiers are optional and can be 750 omitted except module qualifier at top level. 752 3.6.2. Addressing an individual list element 754 Individual list elements have their Paths expressed as: 756 { 757 "module:top-level-container": { 758 "list":[{ 759 "key1":"value1", 760 "key2":"value2" 761 }] 762 } 763 } 765 Figure 34 767 Path is represented as a single branch tree structure containing 768 nested JSON objects up to the list level. 770 At list level the QName is followed by [] to signify a list. The 771 list contains a single object with key-value pairs uniquely 772 identifying the list element. 774 3.6.3. Addressing inside an individual list element 776 Individual list elements have their Paths expressed as: 778 { 779 "module:top-level-container": { 780 "list":[{ 781 "key1":"value1", 782 "key2":"value2", 783 "list-element": {} 784 }] 785 } 786 } 788 Figure 35 790 This form is obtained by adding a path as described in Section 3.6.1 791 section to the list element IId representation described in 792 Section 3.6.2. 794 4. Normative References 796 [AMQP] "AMQP Protocol Specification", 797 . 799 [JABSORB] "Jabsorb JSON RPC Orb and Broker", 800 . 802 [JSONRPC20] 803 Morley, M., "JSON-RPC 2.0 Specification", 2010, 804 . 806 [PJ0MQ] "Python JSON RPC over 0MQ", 807 . 809 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 810 Requirement Levels", BCP 14, RFC 2119, 811 DOI 10.17487/RFC2119, March 1997, 812 . 814 [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 815 Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 816 2014, . 818 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 819 Protocol (HTTP/1.1): Message Syntax and Routing", 820 RFC 7230, DOI 10.17487/RFC7230, June 2014, 821 . 823 [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, 824 DOI 10.17487/RFC7493, March 2015, 825 . 827 [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", 828 RFC 7950, DOI 10.17487/RFC7950, August 2016, 829 . 831 [RFC7951] Lhotka, L., "JSON Encoding of Data Modeled with YANG", 832 RFC 7951, DOI 10.17487/RFC7951, August 2016, 833 . 835 [ZEROMQ] "Zero MQ", . 837 Authors' Addresses 839 Anton Ivanov 840 Cambridge Greys Limited 842 Email: anton.ivanov@cambridgegreys.com 844 David Spence 845 Inocybe Technologies 847 Email: david@roughsketch.co.uk 849 Shaleen Saxena 850 Lumina Networks Inc. 852 Email: shaleen.external@gmail.com 854 Tom Nadeau 855 Lucid Vision LLC 857 Email: tnadeau@lucidvision.com