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);
extern status_t agt_cb_post_sethook_register (const xmlChar *defpath, agt_cb_hook_t cbfn);
defpath | Absolute path expression string indicating which node the callback function is for. |
cbfn | address of callback function to use |
extern void agt_cb_post_sethook_unregister (const xmlChar *defpath);
NOTE:
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:
- Transaction Start
- Set Order Hook for "/if:interface[name=vlan1]"
- Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan2]"
- Set Order Hook for "/if:interface[name=vlan2]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan1]"
- Post Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan3]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan2]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan3]"
- Transaction Complete
Edit on running datastore (after <commit>):
- Transaction Start
- SIL Callback (Validate Phase) for "/if:interface[name=vlan1]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan2]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan3]"
- Validate Complete
- SIL Callback (Apply Phase) for "/if:interface[name=vlan1]"
- SIL Callback (Apply Phase) for "/if:interface[name=vlan2]"
- SIL Callback (Apply Phase) for "/if:interface[name=vlan3]"
- Apply Complete
- SIL Callback (Commit Phase) for "/if:interface[name=vlan1]"
- SIL Callback (Commit Phase) for "/if:interface[name=vlan2]"
- SIL Callback (Commit Phase) for "/if:interface[name=vlan3]"
- Transaction Hook for "/if:interface[name=vlan1]"
- Transaction Hook for "/if:interface[name=vlan2]"
- Transaction Hook for "/if:interface[name=vlan3]"
- Commit/Rollback Complete
- 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:
- Transaction Start
- Set Order Hook for "/if:interface[name=vlan1]"
- Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan2]"
- Set Order Hook for "/if:interface[name=vlan2]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan1]"
- Post Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan3]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan2]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan3]"
- SIL Callback (Apply Phase) for "/if:interface[name=vlan1]"
- SIL Callback (Apply Phase) for "/if:interface[name=vlan2]"
- SIL Callback (Apply Phase) for "/if:interface[name=vlan3]"
- SIL Callback (Commit Phase) for "/if:interface[name=vlan1]"
- SIL Callback (Commit Phase) for "/if:interface[name=vlan2]"
- SIL Callback (Commit Phase) for "/if:interface[name=vlan3]"
- Transaction Hook for "/if:interface[name=vlan1]"
- Transaction Hook for "/if:interface[name=vlan2]"
- Transaction Hook for "/if:interface[name=vlan3]"
- 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:
- Transaction Start
- Set Order Hook for "/if:interface[name=vlan1]"
- Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan2]"
- Set Order Hook for "/if:interface[name=vlan2]"
- SIL Callback (Validate Phase) for "/if:interface[name=vlan1]"
- Post Set Hook for "/if:interface[name=vlan1]" to add "/if:interface[name=vlan3]"
- SIL Callback (Apply Phase) for "/if:interface[name=vlan1]"
- SIL Callback (Commit Phase) for "/if:interface[name=vlan1]"
- Transaction Hook for "/if:interface[name=vlan1]"
- 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>.