The following article illustrates how to handle EDIT2 callbacks for DELETE operation when the target is NP-container and how to access a newly created by the server default NP-container.


In this example, the NP-Container will be populated with non default leaf values and then will be deleted. As a result the EDIT callback function will be invoked and this article will illustrate what values this callback will be invoked with and how to access the default values for this NP-container.


The following YANG modules will be used in this example:


module new-test {
  namespace "http://netconfcentral.org/ns/new-test";
  prefix "new";

  revision "2022-01-01";

  container test-container {
    leaf leaf1 {
      type uint16;
      default "40";
    }
    leaf leaf2 {
      type uint16;
      default "50";
    }
  }
}

The SIL code for the example YANG module can be generated as follows. Refer to the attached code for complete SIL code example:


   user@system ~/modules$ make_sil_dir_pro new-test --sil-get2 --sil-edit2


As a result the following EDIT2 callback will be generated, the callback is already modified to illustrate how to get the default values for target NP-container:


static status_t
    test_container_edit (ses_cb_t *scb,
                         rpc_msg_t *msg,
                         agt_cbtyp_t cbtyp,
                         op_editop_t editop,
                         val_value_t *newval,
                         val_value_t *curval)
{
    status_t res = NO_ERR;
    val_value_t *errorval = (curval) ? curval : newval;
    uint32 cur_errs = agt_get_error_count(msg);

    if (LOGDEBUG) {
        log_debug("\nEnter test_container_edit callback for %s phase",
            agt_cbtype_name(cbtyp));
    }

    switch (cbtyp) {
    case AGT_CB_VALIDATE:
        /* description-stmt validation here */
        break;
    case AGT_CB_APPLY:
        /* database manipulation done here */
        break;
    case AGT_CB_COMMIT:
        /* device instrumentation done here */
        switch (editop) {
        case OP_EDITOP_LOAD:
            break;
        case OP_EDITOP_MERGE:
            handle_merge(msg, newval, curval);
            break;
        case OP_EDITOP_REPLACE:
        case OP_EDITOP_CREATE:
            break;
        case OP_EDITOP_DELETE:
        {
            handle_other(newval, curval);

            status_t res2 = NO_ERR;
            xmlChar *buff = NULL;

            /* Get the default values for current NP container */
            if (curval && obj_npcon_has_defaults(VAL_OBJ(curval))) {

                /* Get the instance ID string for this value node
                 * that will be used in Get Data API
                 */
                res = val_gen_instance_id(NULL,
                                          curval,
                                          NCX_IFMT_XPATH2,
                                          &buff);
                if (res == NO_ERR) {
                    log_info("\nXPath for Curval:%s", buff);

                    /* Get the NP container with default values from
                     * Running datastore. This container will be
                     * set already automatically by netconfd-pro server
                     * and here it will be accessable.
                     */
                    val_value_t *useval =
                        agt_val_get_data(NCX_CFGID_RUNNING,
                                         buff,
                                         &res2);
                    if (useval) {
                        val_dump_value(useval, 10, DBG4);
                    }
                }
            }

            m__free(buff);
            break;
        }
        default:
            /* USE SET_ERROR FOR PROGRAMMING BUGS ONLY */
            res = SET_ERROR(ERR_INTERNAL_VAL);
        }

        break;
    case AGT_CB_ROLLBACK:
        /* undo device instrumentation here */
        break;
    default:
        /* USE SET_ERROR FOR PROGRAMMING BUGS ONLY */
        res = SET_ERROR(ERR_INTERNAL_VAL);
    }

    if ((res != NO_ERR) && (cur_errs == agt_get_error_count(msg))) {
        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;

} /* test_container_edit */

In this EDIT2 callback example, the code provides a way to access the default NP-container that is being created by the netconfd-pro instead of deleted CURVAL.


The following server log illustrates the scenario when the NP-Container was created with non default leaf values and now is being deleted. As a result the EDIT2 callback function  is invoked for DELETE operation.


The server log may look as follows during the DELETE operation and COMMIT Phase:


***** start commit phase on running for session 3, transaction 1488586 *****

Start full commit of transaction 1488586: 1 edit on running config
Start invoking commit SIL callback for delete on new-test:test-container
Enter test_container_edit callback for commit phase
    newval test-container P:[0x7f969c009850] :
          new:test-container {
          }
    curval test-container P:[0x7f969c0049d0] :
          new:test-container {
            leaf1 13
            leaf2 22
          }
child Q of simple childs:   leaf1='13'
child Q of simple childs:   leaf2='22'
XPath for Curval:/new:test-container
agt_val: retrieving '/new:test-container' from running datastore
eval_expr
xpath value result for '/new:test-container'
  typ: nodeset = 
   node VALHDR new:test-container (1)


          new:test-container {
            leaf1 40
            leaf2 50
          }
Finished invoking user callback on new-test:test-container
edit-transaction 1488586: on session 3 by tony@127.0.0.1
  time: 2022-03-03T22:14:39Z
  message-id: 4
  trace-id: --
  datastore: running
  operation: delete
  target: /new:test-container
  comment: none