* Made a separate Clixon datastore XML/JSON top-level symbol

* Replaces the hardcoded "config" keyword.
  * Implemented by a compile-time option called `DATASTORE_TOP_SYMBOL` option in clixon_custom.h
* Tests: added endtest to all tests. Removed all premature exits if BE=0
This commit is contained in:
Olof hagsand 2021-03-05 14:15:15 +01:00
parent 2ab90d847b
commit b7991d9b39
132 changed files with 939 additions and 628 deletions

View file

@ -407,7 +407,7 @@ clixon_client_get_xdata(int sock,
goto done; /* Not fatal */
}
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL){
if ((xd = xml_new("data", NULL, CX_ELMNT)) == NULL)
if ((xd = xml_new(NETCONF_OUTPUT_DATA, NULL, CX_ELMNT)) == NULL)
goto done;
}
else{

View file

@ -217,6 +217,7 @@ xmldb_copy(clicon_handle h,
else if (x2 == NULL){ /* create x2 and copy from x1 */
if ((x2 = xml_new(xml_name(x1), NULL, CX_ELMNT)) == NULL)
goto done;
xml_flag_set(x2, XML_FLAG_TOP);
if (xml_copy(x1, x2) < 0)
goto done;
}
@ -224,6 +225,7 @@ xmldb_copy(clicon_handle h,
xml_free(x2);
if ((x2 = xml_new(xml_name(x1), NULL, CX_ELMNT)) == NULL)
goto done;
xml_flag_set(x2, XML_FLAG_TOP);
if (xml_copy(x1, x2) < 0)
goto done;
}
@ -372,7 +374,7 @@ xmldb_exists(clicon_handle h,
return retval;
}
/*! Clear database cache if any for mem/size optimization only
/*! Clear database cache if any for mem/size optimization only, not file itself
* @param[in] h Clicon handle
* @param[in] db Database
* @retval -1 Error

View file

@ -102,9 +102,9 @@ singleconfigroot(cxobj *xt,
x = NULL;
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL){
i++;
if (strcmp(xml_name(x), "config")){
clicon_err(OE_DB, ENOENT, "Wrong top-element %s expected config",
xml_name(x));
if (strcmp(xml_name(x), DATASTORE_TOP_SYMBOL)){
clicon_err(OE_DB, ENOENT, "Wrong top-element %s expected %s",
xml_name(x), DATASTORE_TOP_SYMBOL);
goto done;
}
}
@ -462,7 +462,7 @@ xmldb_readfile(clicon_handle h,
if ((ret = clixon_json_parse_file(fp, yb, yspec, &x0, NULL)) < 0) /* XXX: ret == 0*/
goto done;
}
else if ((ret = clixon_xml_parse_file(fp, yb, yspec, "</config>", &x0, NULL)) < 0)
else if ((ret = clixon_xml_parse_file(fp, yb, yspec, NULL /* "</config>" XXX */, &x0, NULL)) < 0)
goto done;
#ifdef XMLDB_READFILE_FAIL /* The functions calling this function cannot handle a failed parse yet */
if (ret == 0)
@ -473,7 +473,7 @@ xmldb_readfile(clicon_handle h,
* 1. File is empty <top/> -> rename top-level to "config"
*/
if (xml_child_nr(x0) == 0){
if (xml_name_set(x0, "config") < 0)
if (xml_name_set(x0, DATASTORE_TOP_SYMBOL) < 0)
goto done;
}
/* 2. File is not empty <top><config>...</config></top> -> replace root */
@ -482,6 +482,7 @@ xmldb_readfile(clicon_handle h,
if (singleconfigroot(x0, &x0) < 0)
goto done;
}
xml_flag_set(x0, XML_FLAG_TOP);
if (xml_child_nr(x0) == 0 && de)
de->de_empty = 1;
@ -695,6 +696,7 @@ xmldb_get_cache(clicon_handle h,
/* Make new tree by copying top-of-tree from x0t to x1t */
if ((x1t = xml_new(xml_name(x0t), NULL, CX_ELMNT)) == NULL)
goto done;
xml_flag_set(x1t, XML_FLAG_TOP);
xml_spec_set(x1t, xml_spec(x0t));
if (xlen < 1000){
@ -996,7 +998,7 @@ xmldb_get0_clear(clicon_handle h,
/* clear mark and change */
xml_apply0(x, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
(void*)(0xffff));
(void*)(XML_FLAG_MARK|XML_FLAG_ADD|XML_FLAG_CHANGE));
ok:
retval = 0;
done:

View file

@ -154,7 +154,7 @@ check_body_namespace(cxobj *x0,
/* XXX: need to identify root better than hiereustics and strcmp,... */
isroot = xml_parent(x1p)==NULL &&
strcmp(xml_name(x1p), "config") == 0 &&
strcmp(xml_name(x1p), DATASTORE_TOP_SYMBOL) == 0 &&
xml_prefix(x1p)==NULL;
if (nodeid_split(x1bstr, &prefix, NULL) < 0)
goto done;
@ -935,14 +935,14 @@ xmldb_put(clicon_handle h,
clicon_err(OE_YANG, ENOENT, "No yang spec");
goto done;
}
if (x1 && strcmp(xml_name(x1), "config") != 0){
clicon_err(OE_XML, 0, "Top-level symbol of modification tree is %s, expected \"config\"",
xml_name(x1));
if (x1 && strcmp(xml_name(x1), NETCONF_INPUT_CONFIG) != 0){
clicon_err(OE_XML, 0, "Top-level symbol of modification tree is %s, expected \"%s\"",
xml_name(x1), NETCONF_INPUT_CONFIG);
goto done;
}
if ((de = clicon_db_elmnt_get(h, db)) != NULL){
if (clicon_datastore_cache(h) != DATASTORE_NOCACHE)
x0 = de->de_xml;
x0 = de->de_xml; /* XXX flag is not XML_FLAG_TOP */
}
/* If there is no xml x0 tree (in cache), then read it from file */
if (x0 == NULL){
@ -952,9 +952,10 @@ xmldb_put(clicon_handle h,
if (ret == 0)
goto fail;
}
if (strcmp(xml_name(x0), "config")!=0){
clicon_err(OE_XML, 0, "Top-level symbol is %s, expected \"config\"",
xml_name(x0));
if (strcmp(xml_name(x0), DATASTORE_TOP_SYMBOL) !=0 ||
xml_flag(x0, XML_FLAG_TOP) == 0){
clicon_err(OE_XML, 0, "Top-level symbol is %s, expected \"%s\"",
xml_name(x0), DATASTORE_TOP_SYMBOL);
goto done;
}
/* Here x0 looks like: <config>...</config> */

View file

@ -1232,7 +1232,8 @@ _json_parse(char *str,
*/
if (yspec && xml_prefix(x) == NULL
#ifdef XMLDB_CONFIG_HACK
&& strcmp(xml_name(x), "config") != 0
// && !xml_flag(x, XML_FLAG_TOP)
&& strcmp(xml_name(x), DATASTORE_TOP_SYMBOL) != 0
#endif
){
if ((cberr = cbuf_new()) == NULL){
@ -1261,8 +1262,11 @@ _json_parse(char *str,
break;
case YB_MODULE:
#ifdef XMLDB_CONFIG_HACK
if (strcmp(xml_name(x),"config") == 0 ||
strcmp(xml_name(x),"data") == 0){
if (
// xml_flag(x, XML_FLAG_TOP)
strcmp(xml_name(x), DATASTORE_TOP_SYMBOL) == 0
|| strcmp(xml_name(x), NETCONF_OUTPUT_DATA) == 0
){
/* xt:<top> nospec
* x: <config>
* <a> <-- populate from modules

View file

@ -964,7 +964,7 @@ static const map_str2int clixon_auth_type[] = {
/*! Translate from string to auth-type
*/
const clixon_auth_type_t
const int
clixon_auth_type_str2int(char *auth_type)
{
return clicon_str2int(clixon_auth_type, auth_type);

View file

@ -469,7 +469,7 @@ clicon_rpc_get_config(clicon_handle h,
if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL)
xd = xml_parent(xd); /* point to rpc-reply */
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL){
if ((xd = xml_new("data", NULL, CX_ELMNT)) == NULL)
if ((xd = xml_new(NETCONF_OUTPUT_DATA, NULL, CX_ELMNT)) == NULL)
goto done;
}
else{
@ -831,7 +831,7 @@ clicon_rpc_get(clicon_handle h,
if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL)
xd = xml_parent(xd); /* point to rpc-reply */
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL){
if ((xd = xml_new("data", NULL, CX_ELMNT)) == NULL)
if ((xd = xml_new(NETCONF_OUTPUT_DATA, NULL, CX_ELMNT)) == NULL)
goto done;
}
else{

View file

@ -1905,7 +1905,7 @@ xml_copy_one(cxobj *x0,
default:
break;
}
xml_flag_set(x1, xml_flag(x0, XML_FLAG_DEFAULT)); /* Maybe more flags */
xml_flag_set(x1, xml_flag(x0, XML_FLAG_DEFAULT | XML_FLAG_TOP)); /* Maybe more flags */
retval = 0;
done:
return retval;

View file

@ -82,9 +82,6 @@
#define BUFLEN 1024
/* Indentation for xml pretty-print. Consider option? */
#define XML_INDENT 3
/* Name of xml top object created by xml parse functions */
#define XML_TOP_SYMBOL "top"
/*------------------------------------------------------------------------
* XML printing functions. Output a parse tree to file, string cligen buf
@ -516,8 +513,11 @@ _xml_parse(const char *str,
* x: <a> <-- populate from modules
*/
#ifdef XMLDB_CONFIG_HACK
if (strcmp(xml_name(x),"config") == 0 ||
strcmp(xml_name(x),"data") == 0){
if (
// xml_flag(x, XML_FLAG_TOP)
strcmp(xml_name(x), DATASTORE_TOP_SYMBOL) == 0
|| strcmp(xml_name(x), NETCONF_OUTPUT_DATA) == 0
){
/* xt:<top> nospec
* x: <config>
* <a> <-- populate from modules

View file

@ -1329,7 +1329,7 @@ xml_global_defaults(clicon_handle h,
/* First get or compute global xml tree cache */
if ((de = clicon_db_elmnt_get(h, key)) == NULL){
/* Create it */
if ((xcache = xml_new("config", NULL, CX_ELMNT)) == NULL)
if ((xcache = xml_new(DATASTORE_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL)
goto done;
if (xml_global_defaults_create(xcache, yspec, state) < 0)
goto done;
@ -1353,7 +1353,7 @@ xml_global_defaults(clicon_handle h,
xml_apply_ancestor(x0, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
}
/* Create a new tree and copy over the parts from the cache that matches xpath */
if ((xpart = xml_new("config", NULL, CX_ELMNT)) == NULL)
if ((xpart = xml_new(DATASTORE_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL)
goto done;
if (xml_copy_marked(xcache, xpart) < 0) /* config */
goto done;
@ -1763,11 +1763,12 @@ assign_namespace_element(cxobj *x0, /* source */
char *prefix0 = NULL;;
int isroot;
/* XXX: need to identify root better than hiereustics and strcmp,... */
/* XXX: need to identify root better than hiereustics and strcmp,...
* see XMLDB_CONFIG_HACK
*/
isroot = xml_parent(x1p)==NULL &&
(strcmp(xml_name(x1p), "config") == 0 || strcmp(xml_name(x1p), "top") == 0)&&
xml_flag(x1p, XML_FLAG_TOP) &&
xml_prefix(x1p)==NULL;
/* 1. Find N=namespace(x0) in x0 element */
prefix0 = xml_prefix(x0);
if (xml2ns(x0, prefix0, &namespace) < 0)