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-1
If 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+xml
The 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 ...