Cannot iterate leaf-list item without key

Hi all,

We are trying to traverse operational data. We were able to receive and set “leaf-x” but unable to get all elements of “leaf-list y-list”. We only get first element and could not set cdb.

Here is the related part of my yang file.

container container1  {
            tailf:callpoint "call1";
            config false;
            leaf x {
                type string;
            }
            leaf-list y-list {
                min-elements 1;
                max-elements 2;
                type string;
            }
}

In addition to below definition, In our case we only have one “myEntry”. We do not use “myEntry next” pointer.

Since we do not have any key for “y-list”. We’re trying to use index number instead of key. As you see output below, it iterates get_next once and could not set y-list value to cdb.
What could be wrong here? Is it correct to use index in get_next like this?

int y_list_num;

struct myEntry {
    char *x;
    char **y_list;
    struct myEntry *next;
} myEntry;

struct myData {
    struct myEntry *myEntries;
};

static int get_next(struct confd_trans_ctx *tctx,
                    confd_hkeypath_t *keypath,
                    long next) {
    struct myData *myDataPtr = tctx->t_opaque;  
    confd_value_t v[2];

    if ((next+1) == y_list_num) {
        confd_data_reply_next_key(tctx, NULL, -1,-1);

    } else {
        printf("\n list_val:%s %s  %d\n",myDataPtr->myEntries->y_list[(next+1)],__FILE__,__LINE__);
        CONFD_SET_STR(&v[0],myDataPtr->myEntries->y_list[(next+1)]);
        confd_data_reply_next_key(tctx, &v[0], 1, next+1);
    }
    return CONFD_OK;   
}

static int get_elem(struct confd_trans_ctx *tctx,
                    confd_hkeypath_t *keypath) {
    confd_value_t v;
    struct myData *myDataPtr = tctx->t_opaque;
    if (myDataPtr == NULL) {
        confd_data_reply_not_found(tctx);
        return CONFD_OK;
    }
    switch (CONFD_GET_XMLTAG(&(keypath->v[0][0]))) {
        case x_val:
            CONFD_SET_STR(&v, myDataPtr->myEntries->x);
            break;
        default:
            return CONFD_ERR;
    }
    confd_data_reply_value(tctx, &v);
    return CONFD_OK;
}

Example input

x=“teststr”
y[0]=“str1”
y[1]=“str2”

Output

TRACE CALL data get_elem
(“teststr”)
→ CONFD_OK
TRACE CALL data get_next
list_val:str1
→ CONFD_OK
TRACE CALL trans finish(thandle=82) → CONFD_OK

1 Like

In case of problems with a data provider you should always start by looking into the developer log, any protocol violations (which is likely the problem here) are reported there. You may also want to set /confdConfig/developerLogLevel to trace.

By the way, when your data provider is supposed to handle leaf-lists, it should also implement the exists_optional callback, it is invoked by ConfD when it needs to check particular leaf-list instance.

I added exists_optional callback but did not call that function. We still use get_next right? Do I need to change anything in get_next?

I think trace is set already, I can get trace the logs below.
TRACE CALL data get_elem
(“teststr”)
→ CONFD_OK
TRACE CALL data get_next
list_val:str1
→ CONFD_OK
TRACE CALL trans finish(thandle=82) → CONFD_OK

The important part is in the first paragraph: look for any errors in the developer log (usually devel.log); and to better pinpoint the problem, add

<developerLogLevel>trace</developerLogLevel>

to your confd.conf file.