The leafref type is restricted to the value space of some leaf or leaf-list node in the schema tree and optionally further restricted by corresponding instance nodes in the data tree. The "path" sub-statement is used to identify the referred leaf or leaf-list node in the schema tree. The value space of the referring node is the value space of the referred node.
If the "require-instance" property is "true", the referred node must exist with the same value as the leafref value in a valid data tree.
Consider the following YANG module example:
module example {
namespace "http://yumaworks.com/ns/example";
prefix "example";
revision 2019-07-30 {
description
"Initial example module for leafref type";
}
leaf yang-boolean-example {
type boolean;
}
leaf yang-leafref-example-1 {
type leafref {
path "../yang-boolean-example";
require-instance "false";
}
}
leaf yang-leafref-example-2 {
type leafref {
path "../yang-boolean-example";
require-instance "true";
}
}
}This leaf can be accessed using several ways described below.
1) Using RESTCONF request:
To create a new "yang-leaf-example-1" node using RESTCONF client, the client might send the following POST request:
POST /restconf/data/ HTTP/1.1
Host: example-server
Content-Type: application/yang-data+json
{
"yang-leafref-example-1":"false"
}If the resource is created, the server might respond as follows:
HTTP/1.1 201 Created
Server: example-server
Location: https://example-server/restconf/data/yang-leafref-example-1If the POST method succeeds, a "201 Created" Status is returned and there is no response message-body. A "Location" header field identifying the resource node that was created. If the data resource already exists, then the POST request will fail and a "409 Conflict" status-line will be returned.
To retrieve just created node, the GET method can be sent by the client as follows:
GET /restconf/data/yang-leafref-example-1 HTTP/1.1
Host: example-server
Accept: application/yang-data+xmlThe server might respond as follows:
HTTP/1.1 200 OK
Server: example-server
Content-Type: application/yang-data+xml
<yang-leafref-example-1 xmlns="http://yumaworks.com/ns/example">false</yang-leafref-example-1>A new "yang-leaf-example-2" node cannot be created unless a yang-boolean-example is not present in the data tree using following POST request:
POST /restconf/data/ HTTP/1.1
Host: example-server
Content-Type: application/yang-data+json
{
"yang-leafref-example-1":"false"
}Server might reply with following error message.
{
"ietf-restconf:errors": {
"error": [
{
"error-type":"application",
"error-tag":"data-missing",
"error-app-tag":"instance-required",
"error-path":"/examle:yang-leafref-example-2",
"error-message":"required value instance not found",
"error-info": {
"bad-value":"yang-leafref-example-2",
"error-number":310
}
}
]
}
}2) Using yangcli-pro:
To create a new "yang-leafref-example-1" node using yangcli-pro client, the client might send the following POST request:
user@server> create /yang-leafref-example-1 value=false user@server> commit
To retrieve just created leafref leaf, the following request might be sent:
user@server> sget /yang-leafref-example-1
The server might respond with rpc-reply, containing below information:
<rpc-reply> <data> <yang-leafref-example-1 xmlns="http://yumaworks.com/ns/example">false</yang-leafref-example-1> </data> </rpc-reply>
The following example illustrates how the leafref leaf can be set by using inline JSON file:
edit-config target=candidate config="""
{"config": {
"yang-leafref-example-1" : "false"
}
}
"""The following example illustrates how the leafref leaf can be set by using inline XML file:
edit-config target=candidate config=""" <config> <yang-leafref-example-1>false</yang-leafref-example-1> </config> """
To retrieve just created leafref leaf, the following request might be sent:
user@server> sget /yang-leafref-example-1
The server might respond with rpc-reply, containing below information:
<rpc-reply> <data> <yang-leafref-example-1 xmlns="http://yumaworks.com/ns/example">false</yang-leafref-example-1> </data> </rpc-reply>
Yangcli-pro might parse the above message as
rpc-reply {
data {
yang-leafref-example-1 false
}
}3) Using DB-API:
The following example illustrates how to set leafref leaf value using DB-API.
/********************************************************************
* FUNCTION send_test_edit
*
* This is an example send edit function for leafref node.
**********************************************************************/
static void
send_test_edit (void)
{
const xmlChar *path_str = (const xmlChar *)"/";
const xmlChar *operation_str = (const xmlChar *)"merge";
const xmlChar *value_str = (const xmlChar *)
"<config>"
"<yang-leafref-example-1 xmlns='http://yumaworks.com/ns/example'>false</yang-leafref-example-1>"
"</config>";
const xmlChar *patch_id_str = NULL;
boolean system_edit = FALSE;
status_t res = db_api_send_edit_ex(path_str,
operation_str,
value_str,
patch_id_str,
system_edit);
if (res != NO_ERR) {
log_error("\nSend test edit for leafref node failed %s %s = %s (%s)\n",
operation_str, path_str, value_str,
get_error_string(res));
} else if (LOGDEBUG) {
log_debug("\nSend test edit for leafref node OK %s %s = %s\n",
operation_str, path_str, value_str);
}
} /* send_test_edit */LEAFREF leaf and SIL code:
The following APIs and Macros can be used with the bits type val value node. Refer to val.h:
- val_make_simval_obj(): Function that malloc a new val value node and does not need to know the type, it will be picked automatically based on the provided object type.
- val_get_leafref_typdef(): Function that returns a base type of the referred leaf or leaf-list.
- VAL_STR(): string value assigned.
Following code example creates the value of leafref node and outputs it to the standard log output using val_make_simval_obj().
This is just an example of how the following API can be used:
...
/* create a new leafref type node */
val_value_t *return_val =
val_make_simval_obj(obj, (const xmlChar *)"false", &res);
if (return_val) {
typ_def_t *typdef = NULL;
/* As an example, get the value's type:
* If the value has LEAFREF base type, to get its actual type
* definition would required to call val_get_leafref_typdef()
* API that will return leafref actual type that it points at.
* Otherwise, regular macros could be used VAL_TYPDEF()
*/
if (VAL_BTYPE(return_val) == NCX_BT_LEAFREF) {
typdef = val_get_leafref_typdef(return_val);
} else {
typdef = VAL_TYPDEF(return_val);
}
/* Output the value to the standard output log */
log_info("\nCreated leafref node; type: %s; value: %s",
typdef->typenamestr,
VAL_STR(return_val));
}
...The server might output the following logging information to the standard output:
... Created leafref node; type: boolean; value: false ...