Added top-level namespaces when pruning XML tree for client rpc calls and restconf GET
Added new xmlns_set_all()
This commit is contained in:
parent
9be83d6c7e
commit
ad7232d1ad
13 changed files with 83 additions and 23 deletions
|
|
@ -525,7 +525,6 @@ with_defaults(cxobj *xe, cxobj *xret) {
|
|||
}
|
||||
}
|
||||
}
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ api_data_get2(clicon_handle h,
|
|||
int i;
|
||||
cxobj *x;
|
||||
int ret;
|
||||
char *namespace = NULL;
|
||||
cvec *nsc = NULL;
|
||||
char *attr; /* attribute value string */
|
||||
netconf_content content = CONTENT_ALL;
|
||||
|
|
@ -124,7 +123,8 @@ api_data_get2(clicon_handle h,
|
|||
cxobj *xtop = NULL;
|
||||
cxobj *xbot = NULL;
|
||||
yang_stmt *y = NULL;
|
||||
char *defaults = NULL;
|
||||
char *defaults = NULL;
|
||||
cvec *nscd = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
|
|
@ -266,16 +266,11 @@ api_data_get2(clicon_handle h,
|
|||
switch (media_out){
|
||||
case YANG_DATA_XML:
|
||||
for (i=0; i<xlen; i++){
|
||||
char *prefix;
|
||||
x = xvec[i];
|
||||
/* Some complexities in grafting namespace in existing trees to new */
|
||||
prefix = xml_prefix(x);
|
||||
if (xml_find_type_value(x, prefix, "xmlns", CX_ATTR) == NULL){
|
||||
if (xml2ns(x, prefix, &namespace) < 0)
|
||||
goto done;
|
||||
if (namespace && xmlns_set(x, prefix, namespace) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (xml_nsctx_node(x, &nscd) < 0)
|
||||
goto done;
|
||||
if (xmlns_set_all(x, nscd) < 0)
|
||||
goto done;
|
||||
if (clixon_xml2cbuf(cbx, x, 0, pretty, -1, 0) < 0) /* Dont print top object? */
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -305,6 +300,8 @@ api_data_get2(clicon_handle h,
|
|||
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
|
||||
if (xpath)
|
||||
free(xpath);
|
||||
if (nscd)
|
||||
xml_nsctx_free(nscd);
|
||||
if (nsc)
|
||||
xml_nsctx_free(nsc);
|
||||
if (xtop)
|
||||
|
|
|
|||
|
|
@ -194,8 +194,6 @@ cvec *nscache_get_all(cxobj *x);
|
|||
int nscache_set(cxobj *x, char *prefix, char *ns);
|
||||
int nscache_clear(cxobj *x);
|
||||
int nscache_replace(cxobj *x, cvec *ns);
|
||||
|
||||
int xmlns_set(cxobj *x, char *prefix, char *ns);
|
||||
cxobj *xml_parent(cxobj *xn);
|
||||
int xml_parent_set(cxobj *xn, cxobj *parent);
|
||||
#ifdef XML_PARENT_CANDIDATE
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ int xml_nsctx_cbuf(cbuf *cb, cvec *nsc);
|
|||
|
||||
int xml2ns(cxobj *x, char *localname, char **ns);
|
||||
int xml2ns_recurse(cxobj *x);
|
||||
int xmlns_set(cxobj *x, char *prefix, char *ns);
|
||||
int xmlns_set_all(cxobj *x, cvec *nsc);
|
||||
int xml2prefix(cxobj *xn, char *ns, char **prefixp);
|
||||
|
||||
#endif /* _CLIXON_XML_NSCTX_H */
|
||||
|
|
|
|||
|
|
@ -500,6 +500,7 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
uint32_t session_id;
|
||||
int ret;
|
||||
yang_stmt *yspec;
|
||||
cvec *nscd = NULL;
|
||||
|
||||
if (session_id_check(h, &session_id) < 0)
|
||||
goto done;
|
||||
|
|
@ -554,12 +555,20 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
}
|
||||
}
|
||||
if (xt && xd){
|
||||
/* Sync namespaces, ie explicitly set all xmlns attributes to xd */
|
||||
if (xml_nsctx_node(xd, &nscd) < 0)
|
||||
goto done;
|
||||
if (xml_rm(xd) < 0)
|
||||
goto done;
|
||||
if (xmlns_set_all(xd, nscd) < 0)
|
||||
goto done;
|
||||
xml_sort(xd); /* Ensure attr is first */
|
||||
*xt = xd;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (nscd)
|
||||
cvec_free(nscd);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (xerr)
|
||||
|
|
@ -858,7 +867,7 @@ clicon_rpc_get(clicon_handle h,
|
|||
cvec *nsc, /* namespace context for filter */
|
||||
netconf_content content,
|
||||
int32_t depth,
|
||||
char *defaults,
|
||||
char *defaults,
|
||||
cxobj **xt)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -871,6 +880,7 @@ clicon_rpc_get(clicon_handle h,
|
|||
uint32_t session_id;
|
||||
int ret;
|
||||
yang_stmt *yspec;
|
||||
cvec *nscd = NULL;
|
||||
|
||||
if (session_id_check(h, &session_id) < 0)
|
||||
goto done;
|
||||
|
|
@ -932,12 +942,20 @@ clicon_rpc_get(clicon_handle h,
|
|||
}
|
||||
}
|
||||
if (xt && xd){
|
||||
/* Sync namespaces, ie explicitly set all xmlns attributes to xd */
|
||||
if (xml_nsctx_node(xd, &nscd) < 0)
|
||||
goto done;
|
||||
if (xml_rm(xd) < 0)
|
||||
goto done;
|
||||
if (xmlns_set_all(xd, nscd) < 0)
|
||||
goto done;
|
||||
xml_sort(xd); /* Ensure attr is first */
|
||||
*xt = xd;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (nscd)
|
||||
cvec_free(nscd);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (xerr)
|
||||
|
|
@ -993,6 +1011,7 @@ clicon_rpc_get_pageable_list(clicon_handle h,
|
|||
uint32_t session_id;
|
||||
int ret;
|
||||
yang_stmt *yspec;
|
||||
cvec *nscd = NULL;
|
||||
|
||||
if (datastore == NULL){
|
||||
clicon_err(OE_XML, EINVAL, "datastore not given");
|
||||
|
|
@ -1072,12 +1091,20 @@ clicon_rpc_get_pageable_list(clicon_handle h,
|
|||
}
|
||||
}
|
||||
if (xt && xd){
|
||||
/* Sync namespaces, ie explicitly set all xmlns attributes to xd */
|
||||
if (xml_nsctx_node(xd, &nscd) < 0)
|
||||
goto done;
|
||||
if (xml_rm(xd) < 0)
|
||||
goto done;
|
||||
if (xmlns_set_all(xd, nscd) < 0)
|
||||
goto done;
|
||||
xml_sort(xd); /* Ensure attr is first */
|
||||
*xt = xd;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (nscd)
|
||||
cvec_free(nscd);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (xerr)
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@
|
|||
#include "clixon_handle.h"
|
||||
#include "clixon_yang.h"
|
||||
#include "clixon_xml.h"
|
||||
#include "clixon_xml_nsctx.h"
|
||||
#include "clixon_xml_vec.h"
|
||||
#include "clixon_data.h"
|
||||
#include "clixon_text_syntax_parse.h"
|
||||
|
|
|
|||
|
|
@ -597,6 +597,42 @@ xmlns_set(cxobj *x,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Given an xml node x and a namespace context, add namespace xmlns attributes to x
|
||||
*
|
||||
* As a side-effect, the namespace cache is set
|
||||
* Check if already there
|
||||
* @param[in] x XML tree
|
||||
* @param[in] nsc Namespace context
|
||||
* @note you need to do an xml_sort(x) after the call
|
||||
*/
|
||||
int
|
||||
xmlns_set_all(cxobj *x,
|
||||
cvec *nsc)
|
||||
{
|
||||
int retval = -1;
|
||||
char *ns;
|
||||
char *pf;
|
||||
cg_var *cv = NULL;
|
||||
|
||||
while ((cv = cvec_each(nsc, cv)) != NULL){
|
||||
pf = cv_name_get(cv);
|
||||
/* Check already added */
|
||||
if (pf != NULL) /* xmlns:<prefix>="<uri>" */
|
||||
ns = xml_find_type_value(x, "xmlns", pf, CX_ATTR);
|
||||
else{ /* xmlns="<uri>" */
|
||||
ns = xml_find_type_value(x, NULL, "xmlns", CX_ATTR);
|
||||
}
|
||||
if (ns)
|
||||
continue;
|
||||
ns = cv_string_get(cv);
|
||||
if (ns && xmlns_set(x, pf, ns) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Get prefix of given namespace recursively
|
||||
* @param[in] xn XML node
|
||||
* @param[in] namespace Namespace
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ expectpart "$($clixon_cli -1 -f $cfg -l o debug backend 1)" 0 "^$"
|
|||
|
||||
# Exercise debug code
|
||||
new "get and put config using restconf"
|
||||
expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:table":{"parameter":{"name":"local0","value":"foo"}}}')" 0 "HTTP/$HVER 200" '<data/>' "HTTP/$HVER 201"
|
||||
expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:table":{"parameter":{"name":"local0","value":"foo"}}}')" 0 "HTTP/$HVER 200" "<data $DEFAULTONLY/>" "HTTP/$HVER 201"
|
||||
|
||||
# In freebsd, backend dies in stop_restconf below unless sleep
|
||||
sleep $DEMSLEEP
|
||||
|
|
|
|||
|
|
@ -146,11 +146,11 @@ fi
|
|||
|
||||
# XXX ftest har \n
|
||||
# Only compare relevant data line
|
||||
echo -n "<data>">> $ftest
|
||||
echo -n "<data $DEFAULTONLY>">> $ftest
|
||||
cat $fdataxml >> $ftest
|
||||
echo -n "</data>" >> $ftest
|
||||
# -i (ignore case) dont always work properly
|
||||
sed '/<data>/!d' $foutput > $foutput2
|
||||
sed "/<data $DEFAULTONLY>/!d" $foutput > $foutput2
|
||||
# Strip potential newlines, curl seems to leave trailing newlines on some platforms/versions
|
||||
tr -d "\n\r" < $foutput2 > $foutput
|
||||
|
||||
|
|
|
|||
|
|
@ -161,11 +161,11 @@ if [ $r -ne 0 ]; then
|
|||
fi
|
||||
|
||||
# Only compare relevant data line
|
||||
echo -n "<data>">> $ftest
|
||||
echo -n "<data $DEFAULTONLY>">> $ftest
|
||||
cat $fdataxml >> $ftest
|
||||
#echo "</data>
" >> $ftest
|
||||
echo -n "</data>" >> $ftest
|
||||
sed '/<data>/!d' $foutput > $foutput2
|
||||
sed "/<data $DEFAULTONLY>/!d" $foutput > $foutput2
|
||||
mv $foutput2 $foutput
|
||||
|
||||
ret=$(diff -i $ftest $foutput)
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data)" 0 "H
|
|||
|
||||
#--------------- Multiple request in single TCP tests
|
||||
new "Multiple requests: GET + POST using --next"
|
||||
expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:cont1":{"interface":{"name":"local0","type":"regular"}}}')" 0 "HTTP/$HVER 200" '<data/>' "HTTP/$HVER 201"
|
||||
expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:cont1":{"interface":{"name":"local0","type":"regular"}}}')" 0 "HTTP/$HVER 200" "<data $DEFAULTONLY/>" "HTTP/$HVER 201"
|
||||
|
||||
new "Multiple requests: POST + POST" # XXX Do for HTTP/1 ALSO
|
||||
expectpart "$(curl $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data/example:cont1 -d '{"example:interface":{"name":"local1","type":"regular"}}' --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data/example:cont1 -d '{"example:interface":{"name":"local2","type":"regular"}}')" 0 "HTTP/$HVER 201" "localhost/restconf/data/example:cont1/interface=local1" "localhost/restconf/data/example:cont1/interface=local2"
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ new "PATCH on root resource extra c" # merge extra/c
|
|||
expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data -d '{"ietf-restconf:data":{"example-jukebox:extra":"c"}}')" 0 "HTTP/$HVER 204"
|
||||
|
||||
new "GET check" # XXX: "data" should probably be namespaced?
|
||||
expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data?content=config -H 'Accept: application/yang-data+xml')" 0 "HTTP/$HVER 200" '<extra xmlns="http://example.com/ns/example-jukebox">c</extra>' '<data>'
|
||||
expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data?content=config -H 'Accept: application/yang-data+xml')" 0 "HTTP/$HVER 200" '<extra xmlns="http://example.com/ns/example-jukebox">c</extra>' "<data $DEFAULTONLY>"
|
||||
|
||||
new "Add empty leaf"
|
||||
expectpart "$(curl -u andy:bar $CURLOPTS -X POST $RCPROTO://localhost/restconf/data -H 'Content-Type: application/yang-data+json' -d '{"example-system:system":{"extraleaf":""}}')" 0 "HTTP/$HVER 201"
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPR
|
|||
"HTTP/$HVER 200" \
|
||||
"Content-Type: application/yang-data+xml" \
|
||||
"Cache-Control: no-cache" \
|
||||
'<interface xmlns="http://example.com/ns/interfaces"><name>eth1</name><mtu wd:default="true">1500</mtu><status wd:default="true">ok</status></interface>'
|
||||
'<interface xmlns="http://example.com/ns/interfaces" xmlns:wd="urn:ietf:params:xml:ns:netconf:default:1.0"><name>eth1</name><mtu wd:default="true">1500</mtu><status wd:default="true">ok</status></interface>'
|
||||
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue