Subject: [netmod] RPCs in lists

From: Balazs Lengyel <[email-masked]>
Date: Wed, 29 Oct 2008 02:02:55 +0100

Hello,
On the October Netmod interim and later on the mailing list IMHO there was support to introduce 
rpcs inside lists and containers because a good number of stakeholders are already using or 
planning to use similar features.

Here are two possible solutions of the rpc-in-list concept. One using the existing rpc 
statement and an alternative with a new action statement. A common introduction could be:

--------------------------------------

The most basic way to think about rpcs/actions related to lists/containers is to think about
the following constructs:

Allowed today:
-------------

container root {
    list mainList {
        key mainId;
        leaf mainId {type string;}
    }

     list interface {
        key interfaceId;
        leaf interfaceId {type string;}
    }
}

rpc restart {
      input {
          leaf callingPoint { type instanceidentifier; }
      }
}

augment "/restart/input" {
      when "substring(/restart/input/callingPoint,'/root/mainList')";
      leaf firstLeafForRestartInMainList { type string; }
}

augment "/restart/input" {
      when "substring(/restart/input/callingPoint,'/root/interface')";
      leaf firstLeafForRestartInterface { type string; }
}

   ===================================================================

I would rather like to see a proper syntax for this:

container root {
      list mainList {
          key mainId;
          leaf mainId {type string;}

          rpc restart {
              input {
                  leaf firstLeafForRestartInMainList { type string; }
              }
          }
      }

      list interface {
          key interfaceId;
          leaf interfaceId {type string;}
      }
          rpc restart {
              input {
                  leaf firstLeafForRestartInterface { type string; }
              }
          }
      }
}

--------------------------------------------------------------

The above two definitions would result in the same XML on the wire, which already today, a YANG 
compliant agent must accept (if such agent already exists :-).
In a way the shorter notation can be considered syntactic sugar for defining rpc statements.

For the second notation
- Readability,
- Understandability
- Writability
is much better.

If the rpc/action really manipulates the managed entity
described by the list/container, then the rpc's definition should be done together with the
list/container, and we should not force the reader to find the related rpc 3 pages earlier just
because it has to be defined on the top level.

Encapsulating all definitions affecting the specific list/container, including both data and 
rpcs, is a good thing.

If the rpc is clearly related to the list/container a kind of pointer to the specific
list/container should be included in the rpc.

There are two options when defining the actions/rpcs in lists/containers statements:

- Use the existing rpc statement or alternatively use a new action statement. The two are 
similar in many ways except the implicit calling-point parameter and the encoding. I provided
both options in the attached files.

My proposal is to use the rpc statement, as top level rpcs and rpcs inside lists have more in 
common then what differentiates them.

Balazs

Rpcs in lists/containers
   text for the YANG standard using the existing rpc statement
----------------------------------------------------------------

ADD: rpc will be added as a substatement to list, container and grouping.

** The rpc Statement @rpc@

The "rpc" statement is used to define a NETCONF RPC method.  It takes
one argument, which is an identifier, followed by a block of
substatements that holds detailed rpc information.  This argument is
the name of the RPC, and is used as the element name directly under
the <rpc> element, as designated by the substitution group
"rpcOperation" in ^RFC4741^.

The "rpc" statement defines an rpc node in the schema tree.  Under the
rpc node, an input node with the name "input", and an output node with
the name "output" are also defined.  The nodes "input" and "output" are
defined in the module's namespace.

NEW START------------------------------------------------------------------------------

If the rpc statement is a substatement of a container, a list or 
is part of a grouping that is used inside a container or a list,  
the NETCONF RPC invocation must have as it's first, implicitly defined, 
parameter the calling-point parameter which must contain an 
instance-identifier pointing to a data node, an existing container or list entry, 
coresponding to the schema location where the rpc is defined. 
The RPC is conceptually invoked on that container or list-entry.

NEW END------------------------------------------------------------------------------

***  The rpc's Substatements

!! table
!! head ! substatement      ! section         ! cardinality
!! row  ! description       ! ^description^   ! 0..1
!! row  ! grouping          ! ^grouping^      ! 0..n
!! row  ! if-feature        ! ^if-feature^    ! 0..n
!! row  ! input             ! ^input^         ! 0..1
!! row  ! output            ! ^output^        ! 0..1
!! row  ! reference         ! ^reference^     ! 0..1
!! row  ! status            ! ^status^        ! 0..1
!! row  ! typedef           ! ^typedef^       ! 0..n

*** The input Statement @input@

The "input" statement, which is optional, is used to define input
parameters to the RPC method.  It does not take an argument.  The
substatements to "input" defines nodes under the RPC's input node.

If a container in the input tree has a "presence" statement, the
container need not be present in a NETCONF RPC invocation.

If a leaf in the input tree has a "mandatory" statement with the
value "true", the leaf MUST be present in a NETCONF RPC
invocation.

If a leaf in the input tree has a default value, the NETCONF server
MUST internally use this default if the leaf is not present in a
NETCONF RPC invocation.

If a "config" or "must" statement is present for any node in the
input tree, it is ignored.

****  The input's Substatements

!! table
!! head ! substatement      ! section         ! cardinality
!! row  ! anyxml            ! ^anyxml^        ! 0..n
!! row  ! augment           ! ^augment^       ! 0..n
!! row  ! choice            ! ^choice^        ! 0..n
!! row  ! container         ! ^container^     ! 0..n
!! row  ! grouping          ! ^grouping^      ! 0..n
!! row  ! leaf              ! ^leaf^          ! 0..n
!! row  ! leaf-list         ! ^leaf-list^     ! 0..n
!! row  ! list              ! ^list^          ! 0..n
!! row  ! typedef           ! ^typedef^       ! 0..n
!! row  ! uses              ! ^uses^          ! 0..n

*** The output Statement @output@

The "output" statement, which is optional, is used to define output
parameters to the RPC method.  It does not take an argument.  The
substatements to "output" defines nodes under the RPC's output node.

If a container in the output tree has a "presence" statement, the
container need not be present in a NETCONF RPC reply

If a leaf in the output tree has a "mandatory" statement with the
value "true", the leaf MUST be present in a NETCONF RPC
reply.

If a leaf in the output tree has a default value, the NETCONF client
MUST internally use this default if the leaf is not present in a
NETCONF RPC reply.

If a "config" or "must" statement is present for any node in the
output tree, it is ignored.

****  The output's Substatements

!! table
!! head ! substatement      ! section         ! cardinality
!! row  ! anyxml            ! ^anyxml^        ! 0..n
!! row  ! augment           ! ^augment^       ! 0..n
!! row  ! choice            ! ^choice^        ! 0..n
!! row  ! container         ! ^container^     ! 0..n
!! row  ! grouping          ! ^grouping^      ! 0..n
!! row  ! leaf              ! ^leaf^          ! 0..n
!! row  ! leaf-list         ! ^leaf-list^     ! 0..n
!! row  ! list              ! ^list^          ! 0..n
!! row  ! typedef           ! ^typedef^       ! 0..n
!! row  ! uses              ! ^uses^          ! 0..n

*** XML Encoding Rules

An rpc node is encoded as a child XML element to the <rpc> element
defined in ^RFC4741^.  The element's name is the rpc's identifier, and
its XML namespace is the module's XML namespace.

Input parameters are encoded as child XML elements to the rpc node's
XML element, in the same order as they are defined within the
input statement.

NEW START------------------------------------------------------------------------------

If the rpc statement is a substatement of a container, a list or 
is part of a grouping that is used inside a container or a list 
the <rpc> element will have as it's first child element the 
calling-point parameter, preceeding any elements from the input statement.

NEW END------------------------------------------------------------------------------

If the rpc method invocation succeeded, and no output parameters are
returned, the <rpc-reply> contains a single <ok/> element defined in
^RFC4741^.  If output parameters are returned, they are encoded as
child elements to the <rpc-reply> element defined in ^RFC4741^, in the
same order as they are defined within the output statement.

*** Usage Example

The following example defines an RPC method:

  module rock {
      namespace "http://example.net/rock";
      prefix rock;

      rpc rock-the-house {
          input {
              leaf zip-code {
                  type string;
              }
          }
      }
  }

A corresponding XML encoding of the complete rpc and rpc-reply:

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <rock-the-house xmlns="http://example.net/rock">
      <zip-code>27606-0100</zip-code>
     </rock-the-house>
  </rpc>

  <rpc-reply message-id="101"
             xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <ok/>
  </rpc-reply>  
  
NEW START------------------------------------------------------------------------------

The following example defines an RPC method inside a list:

  module restart {
      namespace "http://example.net/restart";
      prefix restart;

      list interface {
	      key name;
		  leaf name { type string; }
		  
		  rpc restart {
              input {
                  leaf immediate { type boolean; }
              }
          }
      }
  }

A corresponding XML encoding of the complete rpc:

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <restart xmlns="http://example.net/restart">
	  <calling-point>
	    /interface[name='eth0']
	  </calling-point>
      <immediate>true</immediate>
     </restart>
  </rpc>
  
The encoding of the rpc-reply is the same as above.  

NEW END------------------------------------------------------------------------------
Actions text for YANG standard using a new "action" statement
---------------------------------------------------------------

Mention action everywhere rpc is mentioned !!!

Action will be a substatement of list, container and grouping. 
Groupings with actions can only be used inside lists or containers. 
If uses puts them on the top level they are considered a YANG error.

NEW START------------------------------------------------------------------------------

** The action Statement @action@

The "action" statement is used to define a NETCONF RPC method.  It takes
one argument, which is an identifier, the name of the action, followed by a block of
substatements that hold detailed input and output information.  

The action statement is very similar to the rpc statement, however 
the NETCONF RPC encoding of an action will convey a conceptual 
calling point parameter. This MUST point to an existing container or list entry, 
corresponding to the schema location where the action is defined. 
The NETCONF RPC is conceptually invoked on that container or list-entry.

The "action" statement defines an action node in the schema tree.  Under the
action node, an input node with the name "input", and an output node with
the name "output" are also defined.  The nodes "input" and "output" are
defined in the module's namespace. The input node defines the explicitly 
specified parameters of the to the NETCONF RPC method. The output node 
defines output parameters in the RPC-REPLY.

***  The actions's Substatements

!! table
!! head ! substatement      ! section         ! cardinality
!! row  ! description       ! ^description^   ! 0..1
!! row  ! grouping          ! ^grouping^      ! 0..n
!! row  ! if-feature        ! ^if-feature^    ! 0..n
!! row  ! input             ! ^input^         ! 0..1
!! row  ! output            ! ^output^        ! 0..1
!! row  ! reference         ! ^reference^     ! 0..1
!! row  ! status            ! ^status^        ! 0..1
!! row  ! typedef           ! ^typedef^       ! 0..n

*** XML Encoding Rules

An action node is encoded as the content of the <rpc> element
defined in ^RFC4741^.  Under the  <rpc> element there will be a single 
action element from the yang namespace. This will contain a single <data> 
element.
Inside the <data> element an XML subtree will be contained in a 
manner similar to the <edit-config> operation, according to the
possibly multiple levels of lists and containers containing the action.

For containers no leafs or leaf-lists will be encoded, for lists 
only the key leafs will be encoded. Contained lists and containers are 
included in the encoding, only if they are needed to follow the 
containment hierarchy all the way down to the action. 

The above XML subtree will point out the callingpoint in the same manner 
as an element to be changed is pointed out by the XML hierarchy 
in the <edit-config> operation.

At the appropriate level of containment an element with 
the name defined by the action statement's argument will be present. 

TODO: textual description of encoding needs improvement.

Input parameters are encoded as 
subsequent XML child elements, in the same order as they are defined 
within the input statement.

If the NETCONF RPC method invocation succeeded, and no output parameters are
returned, the <rpc-reply> contains a single <ok/> element defined in
^RFC4741^.  If output parameters are returned, they are encoded as
child elements to the <rpc-reply> element defined in ^RFC4741^, in the
same order as they are defined within the output statement.

*** Usage Example

The following example defines an action:

  module reset {
      namespace "http://example.net/reset";
      prefix reset;

      list interface {
	      key name;
		  leaf name { type string; }
		  
		  action reset {
              input {
                  leaf immediate { type boolean; }
              }
          }
      }
  }

A corresponding XML encoding of the complete RPC and RPC-REPLY:

  <rpc message-id="101"
      xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <yang:action xmlns:yang="urn:ietf:params:xml:ns:yang:1.0">
      <data>
        <interface xmlns="http://example.net/reset">
          <name>eth0</name>
          <reset>
            <immediate>true</immediate>
		  </reset
        </interfaces>
      </data>
    </yang:action>
  </rpc>

  <rpc-reply message-id="101"
      xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <ok/>
  </rpc-reply>
_______________________________________________
netmod mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/netmod

---

From: Andy Bierman <[email-masked]>
Date: Tue, 28 Oct 2008 20:19:32 -0700

Balazs Lengyel wrote:
> Hello,
> On the October Netmod interim and later on the mailing list IMHO there 
> was support to introduce rpcs inside lists and containers because a good 
> number of stakeholders are already using or planning to use similar 
> features.
> 
> Here are two possible solutions of the rpc-in-list concept. One using 
> the existing rpc statement and an alternative with a new action 
> statement. A common introduction could be:
> 

I think this first approach is OK, as long as
none of the identifiers in the data-def-stmts are duplicated.

Eventually, we might work on YANG 3.0, as Juergen
suggests, and at that time, maybe YANG++ will be
around to replace YANG.  We should not add complexity
in YANG clauses now to get 1 OO feature, instead of
some big changes later that support lots of OO features.
The 1.0 release train needs to leave the station now!

Andy

> The above two definitions would result in the same XML on the wire, 
> which already today, a YANG compliant agent must accept (if such agent 
> already exists :-).
> Encapsulating all definitions affecting the specific list/container, 
> including both data and rpcs, is a good thing.
> 
> - Use the existing rpc statement or alternatively use a new action 
> statement. The two are similar in many ways except the implicit 
> calling-point parameter and the encoding. I provided
> My proposal is to use the rpc statement, as top level rpcs and rpcs 
> inside lists have more in common then what differentiates them.
> 
> Balazs
> 
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
>