Namespace for augmented data

Hi,

I have a question about augmentations, if I have 3 yang models like

8<----------------------------------------------------------------------
module main {
namespace “http://foo/main”;
prefix m;

revision “2010-06-08”;

container main{
leaf first{
type string;
}
}
}

module one {
namespace “http://foo/one”;
import main { prefix m; }
prefix o;

revision “2010-06-08”;
augment “/m:main” {
leaf bar {
type string;
}
}
}

module two {
namespace “http://foo/two”;
import main { prefix m; }
prefix t;

revision “2010-06-08”;
augment “/m:main” {
leaf bar {
type string;
}
}
}
---------------------------------------------------------------------->8

which add the same leaf to the base model.
When I get the data from confd over netconf I get like:
8<-------------------------------------------


foobar
bar
bar


------------------------------------------->8

which is expected but in my get_elem callback I don’t see anything that can help me identify which one of the “bar” leafs that is asked for.

How do I know which one is asked for?

The general question is how to identify which model the leaf is defined in at runtime, I would like to be able to get the metadata for the leaf and extract the namespace http://foo/one or http://foo/two.

I found a solution to the non unique path problem, I looked in the libconf code and pyapi code and found a way to print the fully unique path that I need.

This is probably not the best way to do this and there is no escaping of data in keys

How is an external data provider supposed to know the unique model path?

static void print_keypath_with_namespaceprefix(char* out, unsigned int maxlength, const confd_hkeypath_t *hkeypath) {
int index;
for (index = hkeypath->len - 1; index >= 0; index–) {
char buf[255] =
{ 0 };
const confd_value_t *v = &(hkeypath->v[index][0]);
switch (v->type) {
case C_XMLTAG: {
appendToOutputString( out, maxlength, “/”);
if (v->val.xmltag.ns) {
snprintf(buf, 255, “%s:”, confd_ns2prefix(v->val.xmltag.ns));
appendToOutputString( out, maxlength, buf );
}
buf[0]=0;
confd_pp_value(buf, 255, v);
appendToOutputString( out, maxlength, buf );
}
break;
case C_NOEXISTS: {
appendToOutputString( out, maxlength, “{}” );
}
break;
default: {
struct confd_cs_node *node;
struct confd_cs_node *key = NULL;
int i = 0;
appendToOutputString( out, maxlength, “{” );
node = confd_find_cs_node(hkeypath, hkeypath->len - index);
if (node != NULL && node->info.keys != NULL)
key = node->children;
while (1) {
buf[0]=0;
confd_val2str(key->info.type, v, buf, 255);
appendToOutputString( out, maxlength, buf );
if (key != NULL)
key = key->next;
v = &(hkeypath->v[index][++i]);
if (v->type == C_NOEXISTS)
break;
appendToOutputString( out, maxlength, " " );
}
appendToOutputString( out, maxlength, “}” );
}
}
}
}

Why do you need a string representation of the path? A (C) data provider get_elem() callback will typically do a switch() on the hash value for the leaf in the hkeypath, see e,g. arpstat.c in the intro/5-c_stats example. For the (extremely unusual in practice) case of non-unique leaf names, it just needs to do a “sub-switch()” on the namespace (CONFD_GET_XMLTAG_NS(&keypath->v[0][0])).

You could perhaps use confd_xpath_pp_kpath() - it will include the prefix “when needed”, i.e. when the namespace of a node differs from that of its parent.

Not sure what you mean - the hkeypath that it receives is a representation of the unique model path. (Obviously, since you were able to generate a unique string path from it.)

We have an architecture where we have the thinnest layer possible to protect our code from confd and therefore we use string keys to identify where in the data model we should read/write/…

Our “confd abstraction layer” is just a few hundred lines of code and isolates the rest of our code from confd perfectly.

We will switch to the confd_xpath_pp_kpath() then since it seem to do what we need.

Hm, I can see that using string values instead of the ConfD-specific “internal values” can make sense in some scenarios (and for a data provider you can actually have ConfD do it for you, by using the CONFD_DAEMON_FLAG_STRINGSONLY flag with confd_init_daemon()). But turning the hkeypaths into strings, and then having to parse the result and do string compares to figure out which part of the data model is referenced, instead of just switch()ing on the integer hash values, doesn’t seem like an obviously good idea to me…

(There is a reason that hkeypaths are used ConfD → application, and “string paths” in the other direction - hkeypaths are simple to analyze but difficult to construct, while “string paths” are difficult to analyze but simple to construct. ConfD does all the hard work in order to make the application writer’s job easier.:-))

Correction: you use CONFD_DAEMON_FLAG_STRINGSONLY with confd_set_daemon_flags().