This article describes how to access some specific node from a SIL callback or any other transaction callbacks.

For SIL-SA support refer to the following article:

How do I access datastore from SIL-SA callbacks?


The Get Data API is used to retrieve data nodes from the server:


/* FUNCTION agt_val_get_data */
val_value_t *
  agt_val_get_data (ncx_cfg_t  cfgid,
                    const xmlChar *defpath,
                    status_t *retres);


typedef enum ncx_cfg_t_ {
    NCX_CFGID_RUNNING,
    NCX_CFGID_CANDIDATE,
    NCX_CFGID_STARTUP
} YPACK ncx_cfg_t;


API Template


  • Type:  Server Utility Function
  • File: agt_val.h

  • Template: agt_val_get_data

  • Inputs:

    • cfgid == datastore enumeration to use (candidate or running)

      • NCX_CFGID_RUNNING

      • NCX_CFGID_CANDIDATE

    • defpath == XPath expression specifying the data instance to add

    • retres == address of return status

  • Outputs:

    • *retres == set to the return status

  • Returns: val_value_t  pointer to data node if found


This function will return value only if there is existing node in the datastore or there is defaults for the node.

Data cannot be saved and used later, can only be used immediately after the call to agt_val_get_data.


If the XPath expression "defpath" matches multiple nodes, then only the first instance is returned.

ERR_NCX_DEF_NOT_FOUND can be returned if the XPath expression contains unknown or ambiguous object names.



Example



Consider we register Transaction Hook callback for the top level /if:interfaces container element. In this example, we will validate the container node with help of the callback and a Get Data API call to retrieve the specific desired node.

Now, whenever the 'interfaces' node is edited, the callback function will be called and perform specific validation actions.

The callback function may look as follows:


/******************************************************************** 
* FUNCTION transhook_callback
* 
* Callback function for server object handler 
* Used to provide a callback for a specific named object 
* 
* Transaction-Hook: 
*   trigger: DELETE /interface
*   effect: 
*       - if testval node exist the CREATE operation will be denied 
*       - if testval is ‘deny-delete’, the operation will be denied 
* 
********************************************************************/ 
static status_t 
    transhook_callback (ses_cb_t *scb, 
                        rpc_msg_t *msg, 
                        agt_cfg_transaction_t *txcb, 
                        op_editop_t editop, 
                        val_value_t  *newval, 
                        val_value_t  *curval) 
{ 
    log_debug("\nEnter Transaction-Hook callback"); 

    status_t res = NO_ERR; 
    status_t res2 = NO_ERR; 
    val_value_t *errorval = (curval) ? curval : newval; 

    const xmlChar *defpath = (const xmlChar *)"/if:interfaces/if:status";

    /* find a test node and validate its value */
    val_value_t *testval = 
        agt_val_get_data(txcb->cfg_id,
                        defpath, 
                         &res2); 

    switch (editop) { 
    case OP_EDITOP_LOAD: 
        break; 
    case OP_EDITOP_MERGE: 
    case OP_EDITOP_REPLACE: 
    case OP_EDITOP_CREATE:
    /* deny an edit, if the test exist */
        if (testval) { 
            res = ERR_NCX_ACCESS_DENIED; 
        } 
        break; 
    case OP_EDITOP_DELETE:
    /* deny an edit, if the test value set to “deny-delete” */
        if (testval && 
            !xml_strcmp(VAL_STR(testval), (const xmlChar *)"deny-delete") {

            res = ERR_NCX_ACCESS_DENIED; 
        } else { 
            res2 = NO_ERR; 
        } 
        break; 
    default: 
        res = SET_ERROR(ERR_INTERNAL_VAL); 
    } 

    if (res != NO_ERR) { 
        agt_record_error(scb, 
                         &msg->mhdr, 
                         NCX_LAYER_CONTENT, 
                         res, 
                         NULL, 
                         (errorval) ? NCX_NT_VAL : NCX_NT_NONE, 
                         errorval, 
                         (errorval) ? NCX_NT_VAL : NCX_NT_NONE, 
                         errorval); 
    }

    return res; 

}  /* hooks_transhook_edit */ 


So whenever some north bound agent edits an /if:interfaces node the callback is invoked and additionally validates the /if:interfaces/if:status node. Based on this validation, the operation can be denied or granted.