Post Set Hook callback - is a postponed Set Hook  callback analogous function that is invoked within the transaction when  an object is modified but AFTER EDIT callback is done for the same  object. When the netconfd-pro server has been configured to provide a candidate configuration, Post Set Hook code will be invoked when changes are done to the <candidate> configuration if the --target=candidate parameter is used.  If --target=running then the Post Set Hook will be invoked at the start of the transaction on the <running> datastore. This callback will be invoked AFTEREDIT1 or EDIT2 callback for the same object. 



NOTE:
This callback will not be invoked in case the --sil-root-check-first is set to TRUE when the server is run with --target=running. The server will ignore the callback and just skip its invocation.

Post Set Hook can be invoked during the Load; However, it  is not allowed to add new edits. So, callbacks are treated as Transaction Hook style callbacks and can perform only validation tasks  and cannot edit datastore. Any add_edit() API during Load will be ignored, it is not an error just skip the call and go back with NO_ERR status.


The following function template definition is used for Post Set Hook callback functions:


/* Typedef of the agt_hook_cb callback */
typedef status_t 
  (*agt_cb_hook_t)(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);


Post Set Hook callback function is hooked into the server with the agt_cb_post_sethook_register function, described below. The registration is done during the Initialization Phase 1  before the startup configuration is loaded into the running configuration database and before running configurations are loaded.


extern status_t
    agt_cb_post_sethook_register (const xmlChar *defpath,
                                  agt_cb_hook_t cbfn);


defpathAbsolute path expression string indicating which node the callback function is for.
cbfnaddress of callback function to use


The following example code illustrates how Post Set Hook callbacks can be  cleaned up. The callbacks cleanup is getting done during Cleanup Phase.


extern void
    agt_cb_post_sethook_unregister (const xmlChar *defpath);

NOTE: 
It is possible to register different callbacks for the same object, for instance, there can be Set Hook and Transaction Hook callbacks registered for the same object, as well as there can be EDIT or GET2  callbacks for the same object. However, in order to cleanup callbacks,  unregister them, you need to run different cleanup functions. The EDIT and GET2 callbacks have their own unregister functions and hook-based callbacks have their own unregister function.

EXAMPLE


For examples, refer to Set Hook callback article How do I use Set Hook callbacks?



Hooks callback interaction with EDIT2 callbacks (target=candidate)


In case there are multiple Set-Hook and  Post Set Hook callbacks registered and the callbacks add several extra edits to the transaction with help of add_edit() API the server will have the following interaction with added edits and normal edits that are coming from PDU. Assume we register Set-Hook callback, Post Set Hook, Set-Order-Hook,  Transaction-Hook and EDIT2 callback for the same list object, for example "ietf-interface" module and "/if:interfaces/if:interface" list object. So any time the "interface" list is getting edited the server invokes Set-Hook and  Post Set Hook callback and adds up extra "interface" in addition to the regular edit. The following callback invocation order is expected in this case:


Edit on candidate datastore:

  1. Transaction Start
  2. Set Order Hook for "/if:interface[name=vlan1]"
  3. Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan2]"
  4. Set Order Hook for "/if:interface[name=vlan2]"
  5. SIL Callback (Validate Phase) for "/if:interface[name=vlan1]"
  6. Post Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan3]"
  7. SIL Callback (Validate Phase) for "/if:interface[name=vlan2]"
  8. SIL Callback (Validate Phase) for "/if:interface[name=vlan3]"
  9. Transaction Complete

Edit on running datastore (after <commit>):

  1. Transaction Start
  2. SIL Callback (Validate Phase) for "/if:interface[name=vlan1]"
  3. SIL Callback (Validate Phase) for "/if:interface[name=vlan2]"
  4. SIL Callback (Validate Phase) for "/if:interface[name=vlan3]"
  5. Validate Complete
  6. SIL Callback (Apply Phase) for "/if:interface[name=vlan1]"
  7. SIL Callback (Apply Phase) for "/if:interface[name=vlan2]"
  8. SIL Callback (Apply Phase) for "/if:interface[name=vlan3]"
  9. Apply Complete
  10. SIL Callback (Commit Phase) for "/if:interface[name=vlan1]"
  11. SIL Callback (Commit Phase) for "/if:interface[name=vlan2]"
  12. SIL Callback (Commit Phase) for "/if:interface[name=vlan3]"
  13. Transaction Hook for "/if:interface[name=vlan1]"
  14. Transaction Hook for "/if:interface[name=vlan2]"
  15. Transaction Hook for "/if:interface[name=vlan3]"
  16. Commit/Rollback Complete
  17. Transaction Complete

Hooks callback interaction with EDIT2 callbacks (target=running)


Assume the same scenario but the default target in this case is set to <running>. The callbacks invocation order is expected to be:

  1. Transaction Start
  2. Set Order Hook for "/if:interface[name=vlan1]"
  3. Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan2]"
  4. Set Order Hook for "/if:interface[name=vlan2]"
  5. SIL Callback (Validate Phase) for "/if:interface[name=vlan1]"
  6. Post Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan3]"
  7. SIL Callback (Validate Phase) for "/if:interface[name=vlan2]"
  8. SIL Callback (Validate Phase) for "/if:interface[name=vlan3]"
  9. SIL Callback (Apply Phase) for "/if:interface[name=vlan1]"
  10. SIL Callback (Apply Phase) for "/if:interface[name=vlan2]"
  11. SIL Callback (Apply Phase) for "/if:interface[name=vlan3]"
  12. SIL Callback (Commit Phase) for "/if:interface[name=vlan1]"
  13. SIL Callback (Commit Phase) for "/if:interface[name=vlan2]"
  14. SIL Callback (Commit Phase) for "/if:interface[name=vlan3]"
  15. Transaction Hook for "/if:interface[name=vlan1]"
  16. Transaction Hook for "/if:interface[name=vlan2]"
  17. Transaction Hook for "/if:interface[name=vlan3]"
  18. Transaction Complete


In case default target is set to <running> there is an option to control callback invocation for added edits with help of a new agt_val_add_edit_max() API:


/********************************************************************
* FUNCTION agt_val_add_edit_max
*
* Create a new edit based on edit_value.
* if its NULL or invalid the error will be generated.
*
* Move or insertion OP available.
* Skip callbacks for added edits option is available.
*
* Only allowed for Set Hooks or Post Set Hook, the rest are ignored.
*
* INPUTS:
*   txcb == transaction in progress
*   defpath == XPath path of object instance
*   edit_value == val_value_t representing newnode in transaction
*           only needed for create, merge, replace, not delete
*
*   edit_operation == <operation string>
*           "create"
*           "delete"
*           "insert"
*           "merge"
*           "move"
*           "replace"
*           "remove"
*
*   insert_where == <insert enum string>
*           "before"
*           "after"
*           "first"
*           "last"
*           Will be used only if the operations are "move" or "insert".
*           Ignored otherwise.
*
*   insert_point == is a XPath encoded string like the defpath. Only for
*           'before' or 'after' insert_where paramter. The insert_where
*           must be set to 'before' or 'after' if insert_point specified.
*           Will be used only if the operations are "move" or "insert".
*           Ignored otherwise.
*           E.g: "/test3[string.1='entry2'][uint32.1='2']"
*
*   skip_cb == TRUE if DO NOT invoke callbacks for an edded edit if any.
*              FALSE if SKIP any callback for added edit
*              including Transaction, EDIT1, EDIT2 callbacks
*              Only when target=running
*
* RETURNS:
*   status
*
*********************************************************************/
extern status_t
    agt_val_add_edit_max (ses_cb_t *scb,
                          rpc_msg_t *msg,
                          agt_cfg_transaction_t *txcb,
                          const xmlChar *defpath,
                          val_value_t *edit_value,
                          const xmlChar *edit_operation,
                          const xmlChar *insert_where,
                          const xmlChar *insert_point,
                          boolean skip_cb);


With help of this API the serer can be told to whether it should invoke callbacks for added edits.

If skip_cb parameter is set to TRUE then the server will not invoke any callback for added edits. That's the callback order will look as follows:


Assume the same scenario but the default target in this case is set to <running>. The callbacks invocation order is expected to be:

  1. Transaction Start
  2. Set Order Hook for "/if:interface[name=vlan1]"
  3. Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan2]"
  4. Set Order Hook for "/if:interface[name=vlan2]"
  5. SIL Callback (Validate Phase) for "/if:interface[name=vlan1]"
  6. Post Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan3]"
  7. SIL Callback (Apply Phase) for "/if:interface[name=vlan1]"
  8. SIL Callback (Commit Phase) for "/if:interface[name=vlan1]"
  9. Transaction Hook for "/if:interface[name=vlan1]"
  10. Transaction Complete

NOTE:

Skip_cb parameter can be used only when the default target <running>.

Otherwise; the server always invoke callback for added edits in case the default target is <candidate>