The server handles XPath and Subtree filtering requests differently, it follows slightly different code path due to the XPath filtering extra complexity that has to be enforced.
In case of <GET> requests with XPath filtering specified the server has to evaluate the XPath expression first before it starts the output process for the request. In order to run evaluation the server has to know that all the nodes specified in the XPath expression exist. For this reason the server first invokes all the necessary callbacks and only after the XPath expression is evaluated the server will start the output process that may also involve GET2 callback invocation.
In case of <GET> requests with Subtree filtering the server outputs the results at the same time it evaluate the Subtree filter, hence the number of GET2 callback may be less then for XPath filtering.
The following example illustrates the difference in <SGET> and <XGET> requests. Consider the following simplified YANG model:
container interfaces { // get2 callback config false; list interface { // get2 callback key key1; leaf key1 { type string; } leaf type { type string; } leaf nexttype { type string; } list port { // get2 callback key key2; leaf key2 { type string; } leaf type { type string; } leaf nexttype { type string; } } } }
The following output would be produced by the server on the following requests:
> sget /interfaces/interface/port/name > xget /interfaces/interface/port/name <output xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <data> <interfaces xmlns="http://yumaworks.com/ns/get2-test"> <interface> <key1>name1</key1> <port> <key2>name1</key2> </port> <port> <key2>name2</key2> </port> </interface> <interface> <key1>name2</key1> <port> <key2>name1</key2> </port> <port> <key2>name2</key2> </port> </interface> </interfaces> </data> </output>
For the above two requests the server may follow the different code path and invoke GET2 callbacks different amount of times for <XGET> and <SGET>.
The following sequence of GET2 callback invocation would be seen in case of the above <SGET> request:
1) Path: '/interfaces': the server triggers Callback for 'interfaces' container - callback returns container child leafs if any 2) Path: '/interfaces/interface': the server triggers Callback for 'interface' list - keys: - no keys in the request specified - callback returns the first list (key1=name1) 3) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name1' - callback returns the first list (key2=name1) 4) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name1' - 'port/key2' = 'name1' - callback returns the next list (key2=name2) 5) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name1' - 'port/key2' = 'name2' - callback returns error (No instance) DONE for 'port' list 6) Path: '/interfaces/interface': the server triggers Callback for 'interface' list - keys: - 'interface/key1' = 'name1' - callback returns the next list (key1=name2) 7) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name2' - callback returns the first list (key2=name1) 8) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name2' - 'port/key2' = 'name1' - callback returns the next list (key2=name2) 9) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name2' - 'port/key2' = 'name2' - callback returns error (No instance) DONE for 'port' list 10) Path: '/interfaces/interface': the server triggers Callback for 'interface' list - keys: - 'interface/key1' = 'name2' - callback returns error (No instance) DONE for 'interface' list
The following sequence of GET2 callback invocation would be seen in case of the above <XGET> request:
------ Context node setup ---------- 1) Path: '/interfaces': the server triggers Callback for 'interfaces' container - callback returns the container child leafs if any 2) Path: '/interfaces/interface': the server triggers Callback for 'interface' list - keys: - no keys in the request specified - callback returns the first list (key1=name1) 3) Path: '/interfaces/interface': the server triggers Callback for 'interface' list - keys: - 'interface/key1' = 'name1' - callback returns the next list (key1=name2) 4) Path: '/interfaces/interface': the server triggers Callback for 'interface' list - keys: - 'interface/key1' = 'name2' - callback returns error (No instance) DONE for 'interface' list 5) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name1' - callback returns the first list (key2=name1) 6) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name1' - 'port/key2' = 'name1' - callback returns the next list (key2=name2) 7) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name1' - 'port/key2' = 'name2' - callback returns error (No instance) DONE for 'port' list 8) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name2' - callback returns the first list (key2=name1) 9) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name2' - 'port/key2' = 'name1' - callback returns the next list (key2=name2) 10) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name2' - 'port/key2' = 'name2' - callback returns error (No instance) DONE for 'port' list ------ Output process ---------- 11) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name1' - 'port/key2' = 'name1' (fixed-value) - callback returns the specified list (key2=name1) 12) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name1' - 'port/key2' = 'name2' (fixed-value) - callback returns the specified list (key2=name2) 13) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name2' - 'port/key2' = 'name1' (fixed-value) - callback returns the specified list (key2=name1) 14) Path: '/interfaces/interface/port': the server triggers Callback for 'port' list - keys: - 'interface/key1' = 'name2' - 'port/key2' = 'name2' (fixed-value) - callback returns the specified list (key2=name2)