AVAILABLE SINCE 20.10-0 RELEASE 


The SIL-SA EDIT2 callback usage is the same as the EDIT2 callback except EDIT2 MERGE handling. The difference is only in the children edits access APIs. Refer to the How do I use EDIT2 callbacks? for more details on how to use EDIT2 callbacks.


In the following example, SIL-SA EDIT2 callback code gets each child edit record in order to retrieve the real edited nodes and the edited operation and merely form the data and prints it to the log. Instead of printing the data an agent could process to the next step and run device instrumentation as required.


Note that the access APIs are different. This is the only difference between SIL-SA and SIL version of the EDIT2 callbacks. 


Refer to the EDIT2 callback section for more details on how to use EDIT2 callbacks. The following example code illustrates how the SIL-SA EDIT2 callback may look like.



/********************************************************************
* FUNCTION  silsa_edit2_callback_example
*
* SIL-SA EDIT2 Callback function for server object handler
* Used to provide a callback sub-mode for
* a specific named object
*
* Path: /interfaces/interface
* Add object instrumentation in COMMIT phase.
*
********************************************************************/
    silsa_edit2_callback_example (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;

    if (LOGDEBUG) {
        log_debug("\nEnter silsa_edit2_callback_example 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:
            /* the edit is not really on this node; need to get
             * each child_undo record to get the real edited nodes
             * and the edited operations
             */
            sil_sa_child_edit_t *child_edit = sil_sa_first_child_edit(msg);
            while (child_edit) {

                op_editop_t child_editop = OP_EDITOP_NONE;
                val_value_t *child_newval = NULL;
                val_value_t *child_curval = NULL;
                xmlChar *newval_str = NULL;
                xmlChar *curval_str = NULL;

                sil_sa_child_edit_fields(child_edit,
                                         &child_editop,
                                         &child_newval,
                                         &child_curval);
                if (child_newval) {
                    newval_str = val_make_sprintf_string(child_newval);
                    if (newval_str == NULL) {
                        return;
                    }
                }
                if (child_curval) {
                    curval_str = val_make_sprintf_string(child_curval);
                    if (curval_str == NULL) {
                        if (newval_str) {
                            m__free(newval_str);
                        }
                        return;
                    }
                }

                log_debug("\n        %s: editop=%s newval=%s curval=%s",
                          child_newval ? VAL_NAME(child_newval) : NCX_EL_NULL,
                          child_editop ? op_editop_name(child_editop) : NCX_EL_NONE,
                          child_newval ? newval_str : NCX_EL_NULL,
                          child_curval ? curval_str : NCX_EL_NULL);

                m__free(newval_str);
                m__free(curval_str);

                child_edit = sil_sa_next_child_edit(child_edit);
            }

            break;
        case OP_EDITOP_REPLACE:
        case OP_EDITOP_CREATE:
            /* the edit is on this list node and the child editop
             * can be treated the same as the parent (even if different)
             * the val_value_t child nodes can be accessed and there
             * are no child_undo records to use
             */
            val_value_t *child_newval = NULL;
            child_newval =
                val_find_child(newval,
                               EXAMPLE_MODNAME,
                               (const xmlChar *)"untagged-ports");

                val_value_t *leaflist_val = child_newval;
                while (leaflist_val) {

                    /**** process child leaf-list edits here ****/

                    leaflist_val = val_next_child_same(leaflist_val);
                }

                /**** process other child edits here if needed ****/

            break;
        case OP_EDITOP_DELETE:
            break;
        default:
            res = SET_ERROR(ERR_INTERNAL_VAL);
        }
        break;
    case AGT_CB_ROLLBACK:
        /* undo device instrumentation here */
        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;

} /* silsa_edit2_callback_example */


SIL-SA EDIT2 Utility Functions


SIL-SA EDIT2 mode, the same way as SIL version, provides extended edit functionality and thus more ways to manage specific edit.


There are SIL-SA EDIT2 mode specific high-level Transaction access and management utilities in netconf/src/sil-sa/sil_sa.h. These functions access the lower-level functions to provide simpler functions for common transaction management tasks.


The following table highlights available functions:

                                                                                                                                                                                       
                

API

           
                

Description

            sil_sa_first_child_edit()        Get the first child node edit record for a given transaction.            
            sil_sa_next_child_edit()                    Get the child edit fields from the undo record.
            sil_sa_child_edit_fields()        Get the child edit fields from the specified undo record.