Edit Transaction Examples
Edit transactions are used to modify configuration datastores. The Database Operations section explains the callback functions that are used to implement an edit transaction. This section provides guidelines and examples for handling various editing procedures.
There are several operations that cause an edit transaction to be executed. The Database Deployment Variants section describes the different internal database deployment options. The Databases variant used on the server will determine which operations are available.
Database Edit APIs (DB-API)
Newval, Curval and Update Parameters
The newval
and curval
parameters that are passed to SIL and SIL-SA
callback functions can be used to implement YANG instrumentation for
configuration data nodes.
The properties and usage of these parameters are explained in this section.
newval
: edit callback input parameternon-NULL: the new value that will be set if the edit succeeds.
NULL: no new value if the edit is a delete operation
curval
: edit callback input parameternon-NULL: the current value that will be replaced if the edit succeeds.
NULL: there is no current value for the node.
The advent of the EDIT3 Callback marks a significant shift in YANG
instrumentation for configuration data nodes, pivoting primarily on the
utilization of the update
value.
The update
value streamlines the update process by providing a composite
Update value, that incorporates latest changes proposed by the user (newval)
along with relevant current values from the datastore (curval).
update
: a merged value of all new and current values from the datastore,streamlining the update process.
non-NULL: replace the existing data with this composite
update
valueNULL: operation is delete - Delete all data from the device
A data node can either be created by YANG default or created by a client edit operation. The edit transaction processing details for YANG defaults depend on the --default-style parameter value used on the server and the YANG data model being processed.
The following example use-cases will be examined:
Leaf with a Default
Leaf without a Default
Non-Presence Container with a Default
Non-Presence Container without a Default
Presence Container with a Default
Presence Container without a Default
The default processing is handled during an edit operation before the SIL or SIL-SA callbacks are invoked. This section contains the following examples:
the details for a first edit to a node by a client operation
the details for an edit to an existing node by a client operation
the details for a delete edit to an existing node by a client operation
The actual edit operations can change in different scenarios. For example, a 'delete' operation followed by a 'create' operation on the <candidate> datastore can be changed to a 'replace' operation on the <running> datastore.
Printing the Value Path String from a SIL Edit Callback
It is very common to print a debug trace when entering a SIL callback function. There is such a debug trace in the auto-generated code by yangdump-pro.
The 'val_gen_instance_id' function is used to get the string value for the path string of the object node for the callback.
-
status_t val_gen_instance_id(xml_msg_hdr_t *mhdr, const val_value_t *val, ncx_instfmt_t format, xmlChar **buff)
Malloc and Generate the instance ID string for this value node,.
- Parameters:
mhdr -- [inout] message hdr w/ prefix map or NULL to just use the internal prefix mappings
mhdr.pmap may have entries added if prefixes used in the instance identifier which are not already in the pmap
val -- node to generate the instance ID for
format -- desired output format (NCX or Xpath)
buff -- [out] pointer to address of buffer to use
*buff malloced buffer with the instance ID
- Returns:
status
The following example uses this small YANG module to show path strings for the 'test3' list node:
container test1 {
list test2 {
key "a b";
leaf a { type int32; }
leaf b { type string; }
list test3 {
key "c d";
leaf c { type string; }
leaf d { type string; }
}
}
}
The following code snippet shows how this function can be used.
if (LOGDEBUG) {
log_debug("\nEnter u_tlist_test3_edit callback for %s phase",
agt_cbtype_name(cbtyp));
/* print the edit operation */
log_debug_append(" op=%s", op_editop_name(editop));
/* print the path string */
val_value_t *useval = newval;
if (useval == NULL) {
useval = curval;
}
if (useval != NULL) {
ncx_instfmt_t format = NCX_IFMT_XPATH2;
xmlChar *buff = NULL;
res = val_gen_instance_id(RPC_MHDR(msg),
useval,
format,
&buff);
if ((res == NO_ERR) && (buff != NULL)) {
log_debug_append("\nPath: %s", buff);
}
m__free(buff);
}
}
The following log trace shows an example list entry being created:
Enter test3_edit callback for commit phase
Enter u_tlist_test3_edit callback for commit phase op=create
Path: /tlist:test1/tlist:test2[tlist:a="100"][tlist:b="test-b"]/tlist:test3[tlist:c="test-c"][tlist:d="test-d"]
Example YANG Module: testdef2
The YANG module modules/test/pass/testdef2.yang
is used as an example for default handling.
module testdef2 {
yang-version 1.1;
namespace "urn:yumaworks:params:xml:ns:yang:testdef2";
prefix "tdef2";
revision 2023-04-07;
leaf defleaf {
type uint32;
default 42;
}
leaf nodefleaf {
type uint32;
}
container npcon {
leaf defleaf2 {
type uint32;
default 142;
}
leaf nodefleaf2 {
type uint32;
}
}
container pcon {
presence "enabled";
leaf defleaf3 {
type uint32;
default 242;
}
leaf nodefleaf3 {
type uint32;
}
}
}
Each example shows the value and source of the newval
, curval
,
and update
parameters that are passed to the edit callback function.
Note
Update value is used only in EDIT3 Callback
A simple debug trace function was added to the edit functions:
static void dump_edit_vals (val_value_t *newval,
val_value_t *curval,
val_value_t *update)
{
if (!LOGDEBUG) {
return;
}
log_debug("\nEdit values:");
if (newval) {
log_debug_append("\nnewval set %s",
val_set_by_default(newval) ?
"by default" : "by client");
val_dump_value(newval, 2, DBG);
} else {
log_debug_append("\nnewval NULL");
}
if (curval) {
log_debug_append("\ncurval set %s",
val_set_by_default(curval) ?
"by default" : "by client");
val_dump_value(curval, 2, DBG);
} else {
log_debug_append("\ncurval NULL");
}
if (update) {
log_debug_append("\nupdate set %s",
val_set_by_default(update) ?
"by default" : "by client");
val_dump_value(update, 2, DBG);
} else {
log_debug_append("\nupdate NULL");
}
} /* dump_edit_vals */
Default Nodes Created During Load Config
The server will usually create default leafs and NP containers during the system <load-config> operation. The defaults are added to an empty datastore or to a datastore with the previous contents from non-volatile storage.
A val_value_t data structure is created for both default and non-default nodes leafs:
The
newval
,curval
, orupdate
parameters could be set by defaultUse function
val_set_by_default
to check if the value was added by the systemUse function
val_is_default
to check if the value is equal to the YANG default value
For this example it is assumed the initial datastore is empty. This is possible many ways, included by use of the --no-startup parameter.
The
curval
is NULL during a load since the datastore is initially empty.The
newval
is set by default.The
update
is the same asnewval
in EDIT3 callbacks.The editop will be
OP_EDITOP_LOAD
The --default-style parameter is ignored during processing.
The
newval
will be set-by-default in all 3 default stylesThe datastore will be <running>.
In this example, there will be SIL callbacks for the 2 nodes that are created by default.
Leaf /defleaf = 42
Start invoking validate SIL callback for load on testdef2:defleaf Enter defleaf_edit callback for validate phase Enter u_tdef2_defleaf_edit callback for validate phase Edit values: newval set by default tdef2:defleaf 42 curval NULL update NULL Finished invoking user callback on testdef2:defleaf
Container /npcon (contains defleaf2 = 142)
Enter npcon_edit callback for validate phase Enter u_tdef2_npcon_edit callback for validate phase Edit values: newval set by default tdef2:npcon { defleaf2 142 } curval NULL update set by default tdef2:npcon { defleaf2 142 } Finished invoking user callback on testdef2:defleaf
Edit Processing For Leafs
The callback details for a leaf are is the simplest of all YANG objects. There is only one instance possible of a leaf.
Note
Top level leafy nodes cannot have EDIT2 nor EDIT3 callbacks. In this case there will be an EDIT1 callback, thus no update value.
For non-delete operations:
The
newval
is non-NULL and is set by a client.The
curval
is non-NULL if there is an existing value for the leaf.The edit operation is a 'set' operation if the editop is one of:
OP_EDITOP_CREATE
OP_EDITOP_MERGE
OP_EDITOP_REPLACE
These operations mean the same thing for leafs and should be treated the same.
For delete operations:
The
newval
is NULLThe
curval
is set-by-default or NULLThe edit operation is a 'delete' operation if the editop is one of:
OP_EDITOP_DELETE
OP_EDITOP_REMOVE
For SIL or SIL-SA callback purposes the value of editop will always be
OP_EDITOP_DELETE
for any form of delete operation used by the client.
Leaf with a Default Value
create /defleaf value=100
Enter u_tdef2_defleaf_edit callback for validate phase Edit values: newval set by client tdef2:defleaf 100 curval set by default tdef2:defleaf 42 update NULL Finished invoking user callback on testdef2:defleaf
There is always a current value for a leaf with a YANG default, even if it is deleted.
replace /defleaf value=101
Enter defleaf_edit callback for validate phase Enter u_tdef2_defleaf_edit callback for validate phase Edit values: newval set by client tdef2:defleaf 101 curval set by client tdef2:defleaf 100 update NULL Finished invoking user callback on testdef2:defleaf
delete /defleaf
Enter u_tdef2_defleaf_edit callback for validate phase Edit values: newval set by default tdef2:defleaf 42 curval set by client tdef2:defleaf 101 update NULL Finished invoking user callback on testdef2:defleaf
Leaf Without a Default Value
create /nodefleaf value=200
Enter u_tdef2_nodefleaf_edit callback for validate phase Edit values: newval set by client tdef2:nodefleaf 200 curval NULL update NULL Finished invoking user callback on testdef2:nodefleaf
replace /nodefleaf value=201
Enter u_tdef2_nodefleaf_edit callback for validate phase Edit values: newval set by client tdef2:nodefleaf 201 curval set by client tdef2:nodefleaf 200 update NULL Finished invoking user callback on testdef2:nodefleaf
delete /nodefleaf
Enter u_tdef2_nodefleaf_edit callback for commit phase Edit values: newval NULL curval set by client tdef2:nodefleaf 201 update NULL Finished invoking user callback on testdef2:nodefleaf
Edit Processing For Containers and Lists
There are 2 types of YANG data nodes that can have child nodes:
non-presence container:
These nodes are created automatically.
The --create-empty-npcontainers parameter controls this behavior during edit operations.
The value can either be set-by-default or set-by-client
presence container or list:
These nodes are not created automatically.
The value is always set-by-client
For non-delete operations:
The
newval
is non-NULL and is set by a client.The
curval
is non-NULL if there is an existing value for the node.The
update
is non-NULL and is a merged value of new and current values.The edit operation is a 'set' operation if the editop is one of:
OP_EDITOP_CREATE
OP_EDITOP_MERGE
OP_EDITOP_REPLACE
These operations mean the same thing only if the current value is set-by-default or NULL.
For delete operations:
The
newval
is NULLThe
curval
is set-by-default or NULLThe
update
is NULLThe edit operation is a 'delete' operation if the editop is one of:
OP_EDITOP_DELETE
OP_EDITOP_REMOVE
For SIL or SIL-SA callback purposes the value of editop will always be
OP_EDITOP_DELETE
for any form of delete operation used by the client.If the --allow-list-delete-all parameter is 'true' then the following edit operations can be in the edit request. -
OP_EDITOP_DELETE_ALL
-OP_EDITOP_REMOVE_ALL
The server will set editop to
OP_EDITOP_DELETE
for each individual list instance.
Non Presence Container with a Default Value
create /npcon (defleaf2 = 242, nodefleaf2 = 243)
Enter u_tdef2_npcon_edit callback for validate phase Edit values: newval set by client tdef2:npcon { defleaf2 242 nodefleaf2 243 } curval set by default tdef2:npcon { defleaf2 142 } update set by client tdef2:npcon { defleaf2 242 nodefleaf2 243 } Finished invoking user callback on testdef2:npcon
Update value is the same as newval for CREATE operation.
replace /npcon (defleaf2 = 143, nodefleaf2 NOT SET)
Enter u_tdef2_npcon_edit callback for validate phase Edit values: newval set by client tdef2:npcon { defleaf2 143 } curval set by client tdef2:npcon { defleaf2 242 nodefleaf2 243 } update set by client tdef2:npcon { defleaf2 143 nodefleaf2 243 } Finished invoking user callback on testdef2:npcon
There is no instance of the 'nodefleaf2' node in 'newval'. The SIL callback for 'npcon' must remove any internal value held for this leaf if its configuration instance is removed.
Update value can be used to update internal values. The technique here is to replace the existing data with this composite Update value.
replace /npcon (defleaf2 NOT SET, nodefleaf2 = 256)
Enter u_tdef2_npcon_edit callback for validate phase Edit values: newval set by client tdef2:npcon { nodefleaf2 256 } curval set by client tdef2:npcon { defleaf2 143 nodefleaf2 243 } update set by client tdef2:npcon { defleaf2 143 nodefleaf2 256 } Finished invoking user callback on testdef2:npcon
Update value can be used to update internal values. The technique here is to replace the existing data with this composite Update value.
delete /npcon
Enter u_tdef2_npcon_edit callback for validate phase Edit values: newval set by default tdef2:npcon { defleaf2 142 } curval set by client tdef2:npcon { defleaf2 143 nodefleaf2 256 } update NULL Finished invoking user callback on testdef2:npcon
Update value is NULL during DELETE operation. Newval contains only defaults.
Presence Containers and Lists
An example for a presence container pcon
is shown.
The callbacks would be quite similar for lists, except
additional key leaf parameters are used.
create /pcon (defleaf3 = 300, nodefleaf3 = 400)
Enter u_tdef2_pcon_edit callback for validate phase Edit values: newval set by client tdef2:pcon { defleaf3 300 nodefleaf3 400 } curval NULL update set by client tdef2:pcon { defleaf3 300 nodefleaf3 400 } Finished invoking user callback on testdef2:pcon
Update value is the same as newval for CREATE operation.
replace /pcon (defleaf3 = 243, nodefleaf3 NOT SET)
Enter u_tdef2_pcon_edit callback for validate phase Edit values: newval set by client tdef2:pcon { defleaf3 243 } curval set by client tdef2:pcon { defleaf3 300 nodefleaf3 400 } update set by client tdef2:pcon { defleaf3 243 nodefleaf3 400 } Finished invoking user callback on testdef2:pcon
Update value can be used to update internal values. The technique here is to replace the existing data with this composite Update value.
replace /npcon (defleaf3 NOT SET, nodefleaf3 = 256)
Enter u_tdef2_pcon_edit callback for validate phase Edit values: newval set by client tdef2:pcon { nodefleaf3 256 } curval set by client tdef2:pcon { defleaf3 243 nodefleaf3 400 } update set by client tdef2:pcon { defleaf3 243 nodefleaf3 256 } Finished invoking user callback on testdef2:pcon
Update value can be used to update internal values. The technique here is to replace the existing data with this composite Update value.
delete /pcon
Enter u_tdef2_pcon_edit callback for validate phase Edit values: newval NULL curval set by client tdef2:pcon { defleaf3 242 nodefleaf3 256 } update NULL Finished invoking user callback on testdef2:pcon
Update value is NULL during DELETE operation. Newval does not contain any defaults and is also NULL.