External database, augmented data and get_next_object

Hi,

We have external database with some data data that we handle and return data with the confd_data_reply_next_object_tag_value_arrays(tctx, no, cnt, 0); function, now we augment the data and need to handle the new data in another piece of our code.

I added a callpoint to the container added by the augmentation and registered the application to handle it.

When I do a get I don’t get any callback to get the data from the callpoint, I get a callback to get the list that is located in the agumneted data but not for the container the list is in.

My guess is that confd wan’t me to return all data including the augmented data in the call to confd_data_reply_next_object_tag_value_arrays right?

Is there a way to use the confd_data_reply_next_object_tag_value_arrays and still get confd to issue a callback to get the augmented container?

simplified example where I would not get the bar leaf in the response for a get since I don’t get a request to get it and the code that handles the main module has no knowledge about the one module.
I do get a get_next_object callback to get the list another-list.

module main {
namespace “http://foo/main”;
prefix m;
revision “2010-06-08”;
container main {
tailf:callpoint cp;
list a-list {
key “first”;
leaf first {
type string;
}
}
}
}

module one {
namespace “http://foo/one”;
import main { prefix m; }
prefix o;
revision “2010-06-08”;
augment “/m:main” {
container lll{
tailf:callpoint cp2;
leaf bar {
type string;
}
list another-list {
key “first”;
leaf first {
type string;
}
}
}
}
}

Hi,

Note that it doesn’t matter if you use augmentation or not. To CDB it is the same with our without augmentation.

The non-presence container exist only for organising the hierarchy of data nodes. Therefore there is nothing to get.

No, the keypath in the get_next_object() callback will tell you what list ConfD is requesting objects / rows from. The container is in that path in your example.

Sub-containers and lists in that list will be requested in another call to your registered callbacks. Skip the containers and sublists in the tag value array constructed. See confd_lib_dp man page “confd_data_reply_tag_value_array” for an example.

Your get_elem(), or your get_object() callback if you haven’t registered a get_elem() callback, will get called for the leaf “bar”.

Hi,

the model I supplied was a little to simplified, the module which augments data to the main module has a config ans state container with a lot of data.

It is the openconfig-platform and openconfig-platform-transceiver yang model that is used in this case.

the augmentation is conditional:

augment “/oc-platform:components/oc-platform:component” {
when “/oc-platform:components/oc-platform:component/” +
“oc-platform:state/oc-platform:type = ‘oc-platform-types:TRANSCEIVER’” {
description
“Augment is active when component is of type TRANSCEIVER”;
}
description
“Adding transceiver data to physical inventory”;

uses port-transceiver-top;

}

our annotation file contains:
tailf:annotate “/oc-platform:components/oc-platform:component/oc-transceiver:transceiver” {
tailf:callpoint OPENCONFIG-TRANSCEIVER {
tailf:opaque ‘OPENCONFIG-TRANSCEIVER’;
}
}

my query is:
filter xmlns:oc-platform=“http://openconfig.net/yang/platform” type=“xpath” select="/components/component[name=‘inventory::entity::80’]"

the log starts with what seems ok.

TRACE CALL data get_elem(thandle=9,/components/component{inventory::entity::80}/name)get_elem

(inventory::entity::80) --> CONFD_OK
TRACE CALL data get_object(thandle=9,/components/component{inventory::entity::80})
get_object
This is my trace of what I add to the returned tag array, I don’t return anything related to the augmented data
leaf /oc-platform:components/component{inventory::entity::80}/name
enter tag: /oc-platform:components/component{inventory::entity::80}/config
leaf /oc-platform:components/component{inventory::entity::80}/config/name
exit tag: /oc-platform:components/component{inventory::entity::80}/config
here are the state leaf that confd shuld use to descide if the transceiver container should be requested
enter tag: /oc-platform:components/component{inventory::entity::80}/state
leaf /oc-platform:components/component{inventory::entity::80}/state/name
leaf /oc-platform:components/component{inventory::entity::80}/state/type
leaf /oc-platform:components/component{inventory::entity::80}/state/id
leaf /oc-platform:components/component{inventory::entity::80}/state/description
leaf /oc-platform:components/component{inventory::entity::80}/state/mfg-name
leaf /oc-platform:components/component{inventory::entity::80}/state/version
leaf /oc-platform:components/component{inventory::entity::80}/state/serial-no
leaf /oc-platform:components/component{inventory::entity::80}/state/part-no
exit tag: /oc-platform:components/component{inventory::entity::80}/state
enter tag: /oc-platform:components/component{inventory::entity::80}/properties
exit tag: /oc-platform:components/component{inventory::entity::80}/properties
enter tag: /oc-platform:components/component{inventory::entity::80}/subcomponents
exit tag: /oc-platform:components/component{inventory::entity::80}/subcomponents
–> CONFD_OK
TRACE CALL data get_next_object(thandle=9, /components/component{inventory::entity::80}/properties/property, -1)
get_next_object
–> CONFD_OK
TRACE CALL data get_next_object(thandle=9, /components/component{inventory::entity::80}/subcomponents/subcomponent, -1)
get_next_object
–> CONFD_OK
TRACE CALL data get_next_object(thandle=9, /components/component, -1)

But after that confd ask for first object again.
TRACE CALL data get_next_object(thandle=9, /components/component, -1)
–> CONFD_OK
TRACE CALL data find_next(thandle=9, /components/component, next, {inventory::entity::99})
–> CONFD_OK
TRACE CALL data get_object(thandle=9,/components/component{inventory::entity::80})
get_object
–> CONFD_OK
here I get a request for the list in the augmented data but not the config and state container
TRACE CALL data get_next_object(thandle=9, /components/component{inventory::entity::80}/transceiver/physical-channels/channel, -1)
–> CONFD_OK
TRACE CALL trans finish(thandle=9) --> CONFD_OK

The reply from the query shows that the type is TRANSCEIVER and the augmentation should be active
<?xml version="1.0" encoding="UTF-8"?> <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2"> <data> <components xmlns="http://openconfig.net/yang/platform"> <component> <name>inventory::entity::80</name> <config> <name>inventory::entity::80</name> </config> <state> <name>inventory::entity::80</name> <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type> <id>serialNum</id> <description>descr</description> <mfg-name>client:1:2:21-22</mfg-name> <version>hwRev</version> <serial-no>serialNum</serial-no> <part-no>serialNum</part-no> </state> </component> </components> </data> </rpc-reply>

If I stop using the get_next_object and get_object and only use the get_next and get_elem then I get a get_elem for each of the augmented leafs so the problem for me seems to be that I return the wrong data in the confd_data_reply_next_object_tag_value_arrays but as far as I can see from the manual I return the correct data.

Is there a way for me to trace something in the libconfd library to see why confd is unhappy with the data I return.

Hi,
You will see more on what’s going on if you enable the developer log, devel.log, on the ConfD side with developerLogLevel set to trace in confd.conf.

Thanks.

I now see that the path points to the same container regardless of where the callpoint is registered

get_object request for callpoint ‘OPENCONFIG-PLATFORM-COMPONENTS’ path /oc-platform:components/component{inventory::entity::80}
devel-c get_object request for callpoint ‘OPENCONFIG-TRANSCEIVER-CONFIG’ path /oc-platform:components/component{inventory::entity::80}
devel-c get_object request for callpoint ‘OPENCONFIG-TRANSCEIVER-STATE’ path /oc-platform:components/component{inventory::entity::80}
devel-c get_next_object request for callpoint ‘OPENCONFIG-TRANSCEIVER’ path /oc-platform:components/component{inventory::entity::80}/transceiver/physical-channels/channel

The callpoints are registered at
path /oc-platform:components/component
path /oc-platform:components/component/transceiver
path /oc-platform:components/component/transceiver/state
path /oc-platform:components/component/transceiver/config

So I can’t use the path to figure out when confd is requesting path /oc-platform:components/component{inventory::entity::80}/transceiver/state container

There is also leafs in the path /oc-platform:components/component{inventory::entity::80}/transceiver container, do I need to add separate callpoints to them as well to have a chance to know when someone is requesting the augmented data?

I would like to be able to have one application that handles the path /oc-platform:components/component and if we add more yang models that augment data to the model I would like to have a separate application that supplies the augmented data.

That works if I add a separate callpoint to all augmented data, is that the recommended way?

in my case a callpoint at the container path /oc-platform:components/component/transceiver and if the model augments single leafs to the model also give them a separate callpoint.

Looking at the information provided, ConfD is, through get_object(), asking for objects / rows in the component list, and lastly, through get_next_object() asking for multiple objects / rows in the channel list.

Seems correct to me?

It is logical when I understood it, the “problem” I try to solve is that the code that supplies data to the /components/component objects/rows for the namespace openconfig-platform should not need to change because someone adds a yang model that augments the original yang model.

The extra data should be supplied by the new application code that is bundled with the new yang model.

I now see that If I add a callpoint to all “root” objects (containers/leafs) that is augmented and let the new application code handle the callpoints I will be able to extend the functionality without modifying the original code.

Since most augmentation I have seen is a single leaf or a new container this will not be a problem to add callpoints to them.

Hi,

I’m still not 100% sure how this is supposed to work.

I made some changes to the yang models and code and now I get the behaviour that confd is requesting data for the callpoint for the augmented data regardless if the condition for the augmentation is fulfilled or not.

first I get the
get_object request for callpoint ‘OPENCONFIG-PLATFORM’ path /oc-platform:components/component{inventory::entity::6}

and I return all data related t that, then I get request for all data (seems strange)
get_next_object request for callpoint ‘OPENCONFIG-PLATFORM’ path /oc-platform:components/component
and last I get the request for data related to the transceiver
get_object request for callpoint ‘OPENCONFIG-PLATFORM-TRANSCEIVER’ path /oc-platform:components/component{inventory::entity::6}

But I get the request for the callpoint in the augmented container even when the augmentation isn’t active.

Do I need to check the condition for the augmentaiton myself in the code to see if I should return any data?

Hi again,

The problem was in the openconfig yang models or in the confd yang compiler, the augmentation when clause caused teh augmentation to be active for all objects if it was active for any.

augment “/oc-platform:components/oc-platform:component” {
when “./oc-platform:state/oc-platform:type = ‘oc-platform-types:TRANSCEIVER’” {
description
“Augment is active when component is of type TRANSCEIVER”;
}
description
“Adding transceiver data to physical inventory”;

uses port-transceiver-top;

}

vs

augment “/oc-platform:components/oc-platform:component” {
when “/oc-platform:components/oc-platform:component/” +
“oc-platform:state/oc-platform:type = ‘oc-platform-types:TRANSCEIVER’” {
description
“Augment is active when component is of type TRANSCEIVER”;
}
description
“Adding transceiver data to physical inventory”;

uses port-transceiver-top;

}

If you look at the examples in RFC 6020 section 7.15.3, you’ll see that for conditional augmentation, what is being added via augmentation is inside the curly braces with the ‘when’ statement. At least the syntax in your last post, your conditional augmentation appears to add nothing, but you would always be augmenting the grouping port-transceiver-top. Try moving the uses into the braces where the when is found, and see if that gives you the behavior you want.