Fixed [xml bind yang error in xml_bind_yang_rpc_reply #175](https://github.com/clicon/clixon/issues/175)
This commit is contained in:
parent
a129756c6c
commit
dee4e87edf
5 changed files with 56 additions and 12 deletions
|
|
@ -112,6 +112,7 @@ Developers may need to change their code
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
|
||||||
|
* Fixed [xml bind yang error in xml_bind_yang_rpc_reply #175](https://github.com/clicon/clixon/issues/175)
|
||||||
* Fixed: [Is there an error with plugin's ca_interrupt setting ? #173](https://github.com/clicon/clixon/issues/173)
|
* Fixed: [Is there an error with plugin's ca_interrupt setting ? #173](https://github.com/clicon/clixon/issues/173)
|
||||||
* Fixed: unknown nodes (for extenstions) did not work when placed directly under a grouping clause
|
* Fixed: unknown nodes (for extenstions) did not work when placed directly under a grouping clause
|
||||||
* Fixed: [Behaviour of Empty LIST Input in RESTCONF JSON #166](https://github.com/clicon/clixon/issues/166)
|
* Fixed: [Behaviour of Empty LIST Input in RESTCONF JSON #166](https://github.com/clicon/clixon/issues/166)
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,9 @@ module clixon-example {
|
||||||
leaf uk{
|
leaf uk{
|
||||||
type string;
|
type string;
|
||||||
}
|
}
|
||||||
|
leaf val{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ example_rpc(clicon_handle h, /* Clicon handle */
|
||||||
cprintf(cbret, "<rpc-reply xmlns=\"%s\"", NETCONF_BASE_NAMESPACE);
|
cprintf(cbret, "<rpc-reply xmlns=\"%s\"", NETCONF_BASE_NAMESPACE);
|
||||||
if ((xp = xml_parent(xe)) != NULL &&
|
if ((xp = xml_parent(xe)) != NULL &&
|
||||||
(msgid = xml_find_value(xp, "message-id"))){
|
(msgid = xml_find_value(xp, "message-id"))){
|
||||||
cprintf(cbret, " message-id=\"%s\">", msgid);
|
cprintf(cbret, " message-id=\"%s\"", msgid);
|
||||||
}
|
}
|
||||||
cprintf(cbret, ">");
|
cprintf(cbret, ">");
|
||||||
if (!xml_child_nr_type(xe, CX_ELMNT))
|
if (!xml_child_nr_type(xe, CX_ELMNT))
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,8 @@ clicon_rpc_netconf(clicon_handle h,
|
||||||
* @param[in] xml XML netconf tree
|
* @param[in] xml XML netconf tree
|
||||||
* @param[out] xret Return XML netconf tree, error or OK
|
* @param[out] xret Return XML netconf tree, error or OK
|
||||||
* @param[out] sp Socket pointer for notification, otherwise NULL
|
* @param[out] sp Socket pointer for notification, otherwise NULL
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
* @code
|
* @code
|
||||||
* cxobj *xret = NULL;
|
* cxobj *xret = NULL;
|
||||||
* int s;
|
* int s;
|
||||||
|
|
@ -345,6 +347,8 @@ clicon_rpc_netconf_xml(clicon_handle h,
|
||||||
char *rpcname;
|
char *rpcname;
|
||||||
cxobj *xreply;
|
cxobj *xreply;
|
||||||
yang_stmt *yspec;
|
yang_stmt *yspec;
|
||||||
|
cxobj *xerr = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
|
|
@ -363,11 +367,24 @@ clicon_rpc_netconf_xml(clicon_handle h,
|
||||||
xml_find_type(xreply, NULL, "rpc-error", CX_ELMNT) == NULL){
|
xml_find_type(xreply, NULL, "rpc-error", CX_ELMNT) == NULL){
|
||||||
yspec = clicon_dbspec_yang(h);
|
yspec = clicon_dbspec_yang(h);
|
||||||
/* Here use rpc name to bind to yang */
|
/* Here use rpc name to bind to yang */
|
||||||
if (xml_bind_yang_rpc_reply(xreply, rpcname, yspec, NULL) < 0)
|
if ((ret = xml_bind_yang_rpc_reply(xreply, rpcname, yspec, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (ret == 0){
|
||||||
|
/* Replace reply with error */
|
||||||
|
if (*xret) {
|
||||||
|
cxobj *xc;
|
||||||
|
if ((xc = xml_child_i(*xret, 0)) != NULL)
|
||||||
|
xml_purge(xc);
|
||||||
|
if (xml_addsub(*xret, xerr) < 0)
|
||||||
|
goto done;
|
||||||
|
xerr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (xerr)
|
||||||
|
xml_free(xerr);
|
||||||
if (cb)
|
if (cb)
|
||||||
cbuf_free(cb);
|
cbuf_free(cb);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -613,9 +613,9 @@ xml_bind_yang_rpc(cxobj *xrpc,
|
||||||
|
|
||||||
/*! Find yang spec association of XML node for outgoing RPC starting with <rpc-reply>
|
/*! Find yang spec association of XML node for outgoing RPC starting with <rpc-reply>
|
||||||
*
|
*
|
||||||
* Incoming RPC has an "input" structure that is not taken care of by xml_bind_yang
|
* Outgoing RPC has an "output" structure that is not taken care of by xml_bind_yang
|
||||||
* @param[in] xrpc XML rpc node
|
* @param[in] xrpc XML rpc node
|
||||||
* @param[in] name Name of RPC (not seen in output/reply)
|
* @param[in] name Name of RPC (not seen in output/reply)
|
||||||
* @param[in] yspec Yang spec
|
* @param[in] yspec Yang spec
|
||||||
* @param[out] xerr Reason for failure, or NULL
|
* @param[out] xerr Reason for failure, or NULL
|
||||||
* @retval 1 OK yang assignment made
|
* @retval 1 OK yang assignment made
|
||||||
|
|
@ -640,10 +640,20 @@ xml_bind_yang_rpc_reply(cxobj *xrpc,
|
||||||
yang_stmt *yo = NULL; /* output */
|
yang_stmt *yo = NULL; /* output */
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
int ret;
|
int ret;
|
||||||
|
cxobj *xerr1 = NULL;
|
||||||
|
char *opname;
|
||||||
|
cbuf *cberr = NULL;
|
||||||
|
|
||||||
if (strcmp(xml_name(xrpc), "rpc-reply")){
|
opname = xml_name(xrpc);
|
||||||
clicon_err(OE_UNIX, EINVAL, "rpc-reply expected");
|
if (strcmp(opname, "rpc-reply")){
|
||||||
goto done;
|
if ((cberr = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cberr, "Internal error, unrecognized netconf operation in backend reply, expected rpc-reply but received: %s", opname);
|
||||||
|
if (xerr && netconf_operation_failed_xml(xerr, "application", cbuf_get(cberr)) < 0)
|
||||||
|
goto done;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
x = NULL;
|
x = NULL;
|
||||||
while ((x = xml_child_each(xrpc, x, CX_ELMNT)) != NULL) {
|
while ((x = xml_child_each(xrpc, x, CX_ELMNT)) != NULL) {
|
||||||
|
|
@ -663,18 +673,31 @@ xml_bind_yang_rpc_reply(cxobj *xrpc,
|
||||||
}
|
}
|
||||||
if (yo != NULL){
|
if (yo != NULL){
|
||||||
xml_spec_set(xrpc, yo);
|
xml_spec_set(xrpc, yo);
|
||||||
if ((ret = xml_bind_yang(xrpc, YB_MODULE, yspec, xerr)) < 0)
|
/* Use a temporary xml error tree since it is stringified in the original error on error */
|
||||||
|
if ((ret = xml_bind_yang(xrpc, YB_PARENT, NULL, &xerr1)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0){
|
||||||
|
if ((cberr = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cberr, "Internal error in backend reply: ");
|
||||||
|
if (netconf_err2cb(xerr1, cberr) < 0)
|
||||||
|
goto done;
|
||||||
|
if (xerr && netconf_operation_failed_xml(xerr, "application", cbuf_get(cberr)) < 0)
|
||||||
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
if (cberr)
|
||||||
|
cbuf_free(cberr);
|
||||||
|
if (xerr1)
|
||||||
|
xml_free(xerr1);
|
||||||
return retval;
|
return retval;
|
||||||
fail:
|
fail:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue