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>.