-->

Yang action vs rpc and anydata vs anyxml

2020-04-13 17:54发布

问题:

I could not understand the exact difference between Yang action vs Yang rpc and as well the difference between anydata vs anyxml. Why someone should model using anydata or anyxml? I tried finding more information about this, but I could not find. Any information on this is very helpful.

回答1:

"rpc" vs. "action"

The difference between an "rpc" and an "action" is that the latter is attached to a specific data node. This node may serve as metadata for the operation to be performed.

The difference between an action and an rpc is that an action is tied to a node in the datastore, whereas an rpc is not. When an action is invoked, the node in the datastore is specified along with the name of the action and the input parameters.

RFC7950, Section 7.15

Suppose you have an array of items, each of which supports individual operations, such as "start", "stop" and "restart". When someone performs such an operation, they are saying something like: "Hey, please restart this specific item instance only". You would model this in YANG 1.1 using a "list" with embedded actions. That way when the operation is performed the server knows exactly which instance you want restarted, stopped or started, since its unique identifier becomes an integral part of the <rpc> payload (or a RESTCONF operation payload).

RFC7950 uses a "server farm" example to demonstrate this. Each server in the farm may be reset.

     module example-server-farm {
       yang-version 1.1;
       namespace "urn:example:server-farm";
       prefix "sfarm";

       import ietf-yang-types {
         prefix "yang";
       }

       list server {
         key name;
         leaf name {
           type string;
         }
         action reset {
           input {
             leaf reset-at {
               type yang:date-and-time;
               mandatory true;
              }
            }
            output {
              leaf reset-finished-at {
                type yang:date-and-time;
                mandatory true;
              }
            }
          }
        }
      }

The matching NETCONF payload followed by a RESTCONF payload ("Hey, please reset 'apache-1' server"):

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <action xmlns="urn:ietf:params:xml:ns:yang:1">
         <server xmlns="urn:example:server-farm">
           <name>apache-1</name>
           <reset>
             <reset-at>2014-07-29T13:42:00Z</reset-at>
           </reset>
         </server>
       </action>
     </rpc>
POST /restconf/data/example-server-farm:server=apache-1/reset HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<input xmlns="urn:example:server-farm">
  <reset-at>2014-07-29T13:42:00Z</reset-at>
</input>

Note the difference in payload encoding. For NETCONF, the <rpc> for actions contains an <action> element in the standard urn:ietf:params:xml:ns:yang:1 namespace followed by an element branch identifying the data node instance, for RESTONF there is /restconf/data instead of /restconf/operations preceding the URI.

In comparison, rpcs are "globals". They always appear at top-level of a YANG module and may or may not apply to the entire device. You could of course implement any action using an rpc statement, but that would require some non-standard way to supply the referenced data node in an argument to the operation with the "input" statement. Someone is also more likely to perform this operation on non-existent instances.

So, the real reason for introducing this statement was convenience. A lot of server implementations relied own YANG extensions to support the same behavior, so it made sense to create a real YANG keyword to define it in a standard way.

"anyxml" vs. "anydata"

The newer keyword has now become the preferred way to model a blob of arbitrary data.

It should be noted that in YANG version 1, "anyxml" was the only statement that could model an unknown hierarchy of data. In many cases, this unknown hierarchy of data is actually modeled in YANG, but the specific YANG data model is not known at design time. In these situations, it is RECOMMENDED to use "anydata" (Section 7.10) instead of "anyxml".

RFC7950, Section 7.11

When RFC6020 was published, YANG modeled data could only be encoded in XML. It made sense to introduce a keyword that represents a blob of arbitrary well-formed XML. But with time, new encodings popped up, such as the JSON encoding used in RESTCONF.

"anyxml" now makes much less sense. Why would a JSON oriented device need to embed XML in its payloads? That is way too cumbersome. So "anydata" was introduced - it models a blob of encoding-agnostic data. If the server is using XML it will be encoded as XML, if JSON is used it will be encoded in JSON, if X is used it will be encoded in X. The only constraint on this data is that it may be modeled with YANG!

The "anydata" statement is used to represent an unknown set of nodes that can be modeled with YANG, except anyxml, but for which the data model is not known at module design time. It is possible, though not required, for the data model for anydata content to become known through protocol signaling or other means that are outside the scope of this document.

RFC7950, Section 7.10