Revert and obsolete the creators attribute feature introduced in 6.2.

This commit is contained in:
Olof hagsand 2024-01-15 14:34:52 +01:00
parent 465a5999fe
commit 88b60daa75
10 changed files with 16 additions and 534 deletions

View file

@ -25,6 +25,12 @@ Expected: February 2024
* Added reference count for shared yang-specs (schema mounts) * Added reference count for shared yang-specs (schema mounts)
* Allowed for sharing yspec+modules between several mountpoints * Allowed for sharing yspec+modules between several mountpoints
### API changes on existing protocol/config features
Users may have to change how they access the system
* Revert the creators attribute feature introduced in 6.2. It is now obsoleted.
It is replaced with a configured `creators` and user/application semantics
### C/CLI-API changes on existing features ### C/CLI-API changes on existing features
Developers may need to change their code Developers may need to change their code

View file

@ -234,14 +234,6 @@ uint16_t xml_flag(cxobj *xn, uint16_t flag);
int xml_flag_set(cxobj *xn, uint16_t flag); int xml_flag_set(cxobj *xn, uint16_t flag);
int xml_flag_reset(cxobj *xn, uint16_t flag); int xml_flag_reset(cxobj *xn, uint16_t flag);
int xml_creator_add(cxobj *xn, char *name);
int xml_creator_rm(cxobj *xn, char *name);
int xml_creator_find(cxobj *xn, char *name);
size_t xml_creator_len(cxobj *xn);
cvec *xml_creator_get(cxobj *xn);
int xml_creator_copy_one(cxobj *x0, cxobj *x1);
int xml_creator_copy_all(cxobj *x0, cxobj *x1);
char *xml_value(cxobj *xn); char *xml_value(cxobj *xn);
int xml_value_set(cxobj *xn, char *val); int xml_value_set(cxobj *xn, char *val);
int xml_value_append(cxobj *xn, char *val); int xml_value_append(cxobj *xn, char *val);

View file

@ -77,6 +77,5 @@ int xml_rpc_isaction(cxobj *xn);
int xml_find_action(cxobj *xn, int top, cxobj **xap); int xml_find_action(cxobj *xn, int top, cxobj **xap);
int purge_tagged_nodes(cxobj *xn, char *ns, char *name, char *value, int keepnode); int purge_tagged_nodes(cxobj *xn, char *ns, char *name, char *value, int keepnode);
int clixon_compare_xmls(cxobj *xc1, cxobj *xc2, enum format_enum format); int clixon_compare_xmls(cxobj *xc1, cxobj *xc2, enum format_enum format);
int xml_creator_tree(cxobj *xt, cxobj **xcreator);
#endif /* _CLIXON_XML_MAP_H_ */ #endif /* _CLIXON_XML_MAP_H_ */

View file

@ -442,56 +442,6 @@ disable_nacm_on_empty(cxobj *xt,
return retval; return retval;
} }
/*! Read creator data from meta-data and add to xml internal annotation
*
* Iterate creator meta-data using xpaths and create internal creator annotations
* @param[in] h Clixon handle
* @param[in] xt XML top node
* @param[in] xn XML creators node
* On the form:
* <creator>
* <name>testA[name='foo']</name>
* <xpath>...</xpath>
* ...
* </creator>
* @see xml_creator_metadata_write
*/
static int
xml_creator_metadata_read(clixon_handle h,
cxobj *xn)
{
int retval = -1;
cxobj *xt;
cxobj *xc;
cxobj *xp;
cxobj *x;
char *name;
char *xpath;
xt = xml_root(xn);
xc = NULL;
while ((xc = xml_child_each(xn, xc, CX_ELMNT)) != NULL) {
if (strcmp(xml_name(xc), "creator"))
continue;
if ((name = xml_find_body(xc, "name")) == NULL)
continue;
xp = NULL;
while ((xp = xml_child_each(xc, xp, CX_ELMNT)) != NULL) {
if (strcmp(xml_name(xp), "path"))
continue;
if ((xpath = xml_body(xp)) == NULL)
continue;
if ((x = xpath_first(xt, NULL, "%s", xpath)) == NULL)
continue;
if (xml_creator_add(x, name) < 0)
goto done;
}
}
retval = 0;
done:
return retval;
}
/*! Common read function that reads an XML tree from file /*! Common read function that reads an XML tree from file
* *
* @param[in] th Datastore text handle * @param[in] th Datastore text handle
@ -593,19 +543,6 @@ xmldb_readfile(clixon_handle h,
xml_flag_set(x0, XML_FLAG_TOP); xml_flag_set(x0, XML_FLAG_TOP);
if (xml_child_nr(x0) == 0 && de) if (xml_child_nr(x0) == 0 && de)
de->de_empty = 1; de->de_empty = 1;
/* Check if creator attributes are supported*/
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
if ((x = xpath_first(x0, NULL, "creators")) != NULL){
ns = NULL;
if (xml2ns(x, NULL, &ns) < 0)
goto done;
if (strcmp(ns, CLIXON_LIB_NS) == 0){
if (xml_creator_metadata_read(h, x) < 0)
goto done;
xml_purge(x);
}
}
}
/* Check if we support modstate */ /* Check if we support modstate */
if (clicon_option_bool(h, "CLICON_XMLDB_MODSTATE")) if (clicon_option_bool(h, "CLICON_XMLDB_MODSTATE"))
if ((msdiff = modstate_diff_new()) == NULL) if ((msdiff = modstate_diff_new()) == NULL)

View file

@ -493,7 +493,6 @@ text_modify(clixon_handle h,
char *restype; char *restype;
int ismount = 0; int ismount = 0;
yang_stmt *mount_yspec = NULL; yang_stmt *mount_yspec = NULL;
char *creator = NULL;
if (x1 == NULL){ if (x1 == NULL){
clixon_err(OE_XML, EINVAL, "x1 is missing"); clixon_err(OE_XML, EINVAL, "x1 is missing");
@ -534,13 +533,6 @@ text_modify(clixon_handle h,
clicon_data_set(h, "objectexisted", "true"); clicon_data_set(h, "objectexisted", "true");
} }
} }
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
/* Special clixon-lib attribute for keeping track of creator of objects */
if ((ret = attr_ns_value(x1, "creator", CLIXON_LIB_NS, cbret, &creator)) < 0)
goto done;
if (ret == 0)
goto fail;
}
x1name = xml_name(x1); x1name = xml_name(x1);
if (yang_keyword_get(y0) == Y_LEAF_LIST || if (yang_keyword_get(y0) == Y_LEAF_LIST ||
@ -703,10 +695,6 @@ text_modify(clixon_handle h,
xml_flag_reset(x0, XML_FLAG_DEFAULT); xml_flag_reset(x0, XML_FLAG_DEFAULT);
} }
} /* x1bstr */ } /* x1bstr */
if (creator){
if (xml_creator_add(x0, creator) < 0)
goto done;
}
if (changed){ if (changed){
if (xml_insert(x0p, x0, insert, valstr, NULL) < 0) if (xml_insert(x0p, x0, insert, valstr, NULL) < 0)
goto done; goto done;
@ -807,11 +795,6 @@ text_modify(clixon_handle h,
* original object is not reverted. * original object is not reverted.
*/ */
if (x0){ if (x0){
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
/* Recursively copy creator attributes from existing tree */
if (xml_creator_copy_all(x0, x1) < 0)
goto done;
}
xml_purge(x0); xml_purge(x0);
x0 = NULL; x0 = NULL;
} }
@ -862,10 +845,6 @@ text_modify(clixon_handle h,
#ifdef XML_PARENT_CANDIDATE #ifdef XML_PARENT_CANDIDATE
xml_parent_candidate_set(x0, x0p); xml_parent_candidate_set(x0, x0p);
#endif #endif
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
if (xml_creator_copy_one(x1, x0) < 0)
goto done;
}
changed++; changed++;
/* Get namespace from x1 /* Get namespace from x1
* Check if namespace exists in x0 parent * Check if namespace exists in x0 parent
@ -962,10 +941,6 @@ text_modify(clixon_handle h,
if (ret == 0) if (ret == 0)
goto fail; goto fail;
} }
if (creator){
if (xml_creator_add(x0, creator) < 0)
goto done;
}
if (changed){ if (changed){
#ifdef XML_PARENT_CANDIDATE #ifdef XML_PARENT_CANDIDATE
xml_parent_candidate_set(x0, NULL); xml_parent_candidate_set(x0, NULL);
@ -1007,8 +982,6 @@ text_modify(clixon_handle h,
free(instr); free(instr);
if (opstr) if (opstr)
free(opstr); free(opstr);
if (creator)
free(creator);
if (createstr) if (createstr)
free(createstr); free(createstr);
if (nscx1) if (nscx1)
@ -1239,7 +1212,6 @@ xmldb_put(clixon_handle h,
int firsttime = 0; int firsttime = 0;
int pretty; int pretty;
cxobj *xerr = NULL; cxobj *xerr = NULL;
cxobj *xmeta = NULL;
if (cbret == NULL){ if (cbret == NULL){
clixon_err(OE_XML, EINVAL, "cbret is NULL"); clixon_err(OE_XML, EINVAL, "cbret is NULL");
@ -1355,18 +1327,6 @@ xmldb_put(clixon_handle h,
goto done; goto done;
} }
pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY"); pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY");
/* Add creator attributes to datastore */
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
/* @see xml_creator_metadata_read */
if (xml_creator_tree(x0, &xmeta) < 0)
goto done;
if (xml_addsub(x0, xmeta) < 0)
goto done;
if (xml_child_nr_type(xmeta, CX_ELMNT) == 0){
xml_purge(xmeta);
xmeta = NULL;
}
}
if (strcmp(format,"json")==0){ if (strcmp(format,"json")==0){
if (clixon_json2file(f, x0, pretty, fprintf, 0, 0) < 0) if (clixon_json2file(f, x0, pretty, fprintf, 0, 0) < 0)
goto done; goto done;
@ -1377,10 +1337,6 @@ xmldb_put(clixon_handle h,
*/ */
if (xmodst && xml_purge(xmodst) < 0) if (xmodst && xml_purge(xmodst) < 0)
goto done; goto done;
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR") && xmeta){
if (xml_purge(xmeta) < 0)
goto done;
}
retval = 1; retval = 1;
done: done:
if (f != NULL) if (f != NULL)

View file

@ -186,8 +186,6 @@ struct xml{
yang_stmt *x_spec; /* Pointer to specification, eg yang, yang_stmt *x_spec; /* Pointer to specification, eg yang,
by reference, dont free */ by reference, dont free */
cg_var *x_cv; /* Cached value as cligen variable (set by xml_cmp) */ cg_var *x_cv; /* Cached value as cligen variable (set by xml_cmp) */
cvec *x_creators; /* Support clixon-lib creator annotation.
Only if CLICON_NETCONF_CREATOR_ATTR = true */
#ifdef XML_EXPLICIT_INDEX #ifdef XML_EXPLICIT_INDEX
struct search_index *x_search_index; /* explicit search index vectors */ struct search_index *x_search_index; /* explicit search index vectors */
#endif #endif
@ -640,186 +638,6 @@ xml_flag_reset(cxobj *xn,
return 0; return 0;
} }
/*! Add a creator tag
*
* @param[in] xn XML tree
* @param[in] name Name of creator tag
* @retval 0 OK
* @retval -1 Error
*/
int
xml_creator_add(cxobj *xn,
char *name)
{
int retval = -1;
cg_var *cv;
if (!is_element(xn))
goto ok;
if (xn->x_creators == NULL){
if ((xn->x_creators = cvec_new(0)) == NULL){
clixon_err(OE_XML, errno, "cvec_new");
goto done;
}
}
if ((cv = cvec_find(xn->x_creators, name)) == NULL)
cvec_add_string(xn->x_creators, name, NULL);
ok:
retval = 0;
done:
return retval;
}
/*! Remove a creator tag
*
* @param[in] xn XML tree
* @param[in] name Name of creator tag
* @retval 0 OK
* @retval -1 Error
*/
int
xml_creator_rm(cxobj *xn,
char *name)
{
cg_var *cv;
if (!is_element(xn))
return 0;
if ((cv = cvec_find(xn->x_creators, name)) == NULL)
return 0;
return cvec_del(xn->x_creators, cv);
}
/*! Find a creator string
*
* @param[in] xn XML tree
* @param[in] name Name of creator tag
* @retval 1 Yes, xn is tagged with creator tag "name"
* @retval 0 No, xn is not tagged with creator tag "name"
*/
int
xml_creator_find(cxobj *xn,
char *name)
{
if (!is_element(xn))
return 0;
if (xn->x_creators != NULL &&
cvec_find(xn->x_creators, name) != NULL)
return 1;
return 0;
}
/*! Get number of creator strings
*
* @param[in] xn XML tree
* @retval len Number of creator tags assigned to xn
* @retval 0 No creator tags or non-applicable
*/
size_t
xml_creator_len(cxobj *xn)
{
if (!is_element(xn))
return 0;
if (xn->x_creators)
return cvec_len(xn->x_creators);
else
return 0;
}
/*! Get all creator attributes
*/
cvec*
xml_creator_get(cxobj *xn)
{
if (!is_element(xn))
return 0;
return xn->x_creators;
}
/*! Copy creator info from x0 to x1 single object
*
* @param[in] x0 Source XML node
* @param[in] x1 Destination XML node
* @retval 0 OK
* @retval -1 Error
*/
int
xml_creator_copy_one(cxobj *x0,
cxobj *x1)
{
int retval = -1;
if (x0->x_creators)
if ((x1->x_creators = cvec_dup(x0->x_creators)) == NULL){
clixon_err(OE_UNIX, errno, "cvec_dup");
goto done;
}
retval = 0;
done:
return retval;
}
/*! Recursively copy creator attributes from existing tree based on equivalence algorithm
*
* @param[in] x0 Source XML node
* @param[in] x1 Destination XML node
* @retval 0 OK
* @retval -1 Error
* @see xml_tree_equal equivalence algorithm
*/
int
xml_creator_copy_all(cxobj *x0,
cxobj *x1)
{
int retval = -1;
int eq;
cxobj *x0c; /* x0 child */
cxobj *x1c; /* x1 child */
yang_stmt *yc0;
yang_stmt *yc1;
/* Traverse x0 and x1 in lock-step */
x0c = x1c = NULL;
x0c = xml_child_each(x0, x0c, CX_ELMNT);
x1c = xml_child_each(x1, x1c, CX_ELMNT);
for (;;){
if (x0c == NULL || x1c == NULL)
goto ok;
eq = xml_cmp(x0c, x1c, 0, 0, NULL);
if (eq < 0){
x0c = xml_child_each(x0, x0c, CX_ELMNT);
continue;
}
else if (eq > 0){
x1c = xml_child_each(x1, x1c, CX_ELMNT);
continue;
}
else { /* equal */
/* Both x0c and x1c exists and are equal, check if they are yang-equal. */
yc0 = xml_spec(x0c);
yc1 = xml_spec(x1c);
if (yc0 && yc1 && yc0 != yc1){ /* choice */
;
}
else {
if (x0c->x_creators){
if (xml_creator_copy_one(x0c, x1c) < 0)
goto done;
}
else if (xml_creator_copy_all(x0c, x1c) < 0)
goto done;
}
}
x0c = xml_child_each(x0, x0c, CX_ELMNT);
x1c = xml_child_each(x1, x1c, CX_ELMNT);
}
ok:
retval = 0;
done:
return retval;
}
/*! Get value of xnode /*! Get value of xnode
* *
* @param[in] xn xml node * @param[in] xn xml node
@ -2148,8 +1966,6 @@ xml_free(cxobj *x)
#ifdef XML_EXPLICIT_INDEX #ifdef XML_EXPLICIT_INDEX
xml_search_index_free(x); xml_search_index_free(x);
#endif #endif
if (x->x_creators)
cvec_free(x->x_creators);
break; break;
case CX_BODY: case CX_BODY:
case CX_ATTR: case CX_ATTR:
@ -2192,8 +2008,6 @@ xml_copy_one(cxobj *x0,
switch (xml_type(x0)){ switch (xml_type(x0)){
case CX_ELMNT: case CX_ELMNT:
xml_spec_set(x1, xml_spec(x0)); xml_spec_set(x1, xml_spec(x0));
if (xml_creator_copy_one(x0, x1) < 0)
goto done;
break; break;
case CX_BODY: case CX_BODY:
case CX_ATTR: case CX_ATTR:

View file

@ -2034,90 +2034,3 @@ clixon_compare_xmls(cxobj *xc1,
unlink(filename2); unlink(filename2);
return retval; return retval;
} }
/*! Add creator data to metadata xml object on the form name:xpath*
*
* Callback function type for xml_apply
* @param[in] x XML node
* @param[in] arg General-purpose argument
* @retval 2 Locally abort this subtree, continue with others
* @retval 1 Abort, dont continue with others, return 1 to end user
* @retval 0 OK, continue
* @retval -1 Error, aborted at first error encounter, return -1 to end user
* On the form:
* <creator>
* <name>testA[name='foo']</name>
* <xpath>...</xpath>
* ...
* </creator>
*/
static int
xml_creator_one(cxobj *x,
void *arg)
{
int retval = -1;
cxobj *xmeta = (cxobj*)arg;
cxobj *xmc;
cvec *cvv;
cg_var *cv;
char *val;
cvec *nsc = NULL;
char *xpath = NULL;
if ((cvv = xml_creator_get(x)) == NULL){
retval = 0;
goto done;
}
/* Note this requires x to have YANG spec */
if (xml2xpath(x, nsc, 0, 0, &xpath) < 0)
goto done;
cv = NULL;
while ((cv = cvec_each(cvv, cv)) != NULL){
val = cv_name_get(cv);
/* Find existing entry where name is val */
xmc = NULL;
while ((xmc = xml_child_each(xmeta, xmc, CX_ELMNT)) != NULL){
if (strcmp(xml_find_body(xmc, "name"), val) == 0)
break;
}
if (xmc != NULL){
if (clixon_xml_parse_va(YB_NONE, NULL, &xmc, NULL, "<path>%s</path>", xpath) < 0)
goto done;
}
else {
if (clixon_xml_parse_va(YB_NONE, NULL, &xmeta, NULL,
"<creator><name>%s</name><path>%s</path></creator>",
val, xpath) < 0)
goto done;
}
}
retval = 2;
done:
if (xpath)
free(xpath);
return retval;
}
/*! Create creator data tree on the form (name:xpath*)*
*
* @param[in] xt XML top-level node, where to look for creator attributes
* @param[out] xcreators Created XML tree on the form <creators><creator>...
* @retval 0 OK
* @retval -1 Error
*/
int
xml_creator_tree(cxobj *xt,
cxobj **xcreators)
{
int retval = -1;
if ((*xcreators = xml_new("creators", NULL, CX_ELMNT)) == NULL)
goto done;
if (xmlns_set(*xcreators, NULL, CLIXON_LIB_NS) < 0)
goto done;
if (xml_apply(xt, CX_ELMNT, xml_creator_one, *xcreators) < 0)
goto done;
retval = 0;
done:
return retval;
}

View file

@ -1,139 +0,0 @@
#!/usr/bin/env bash
# test for data creator attribute: add same object from sessions s1 and s2
# Restart and ensure attributes remain
# Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
cfg=$dir/conf.xml
fyang=$dir/clixon-example.yang
: ${clixon_util_xpath:=clixon_util_xpath}
cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
<CLICON_CLISPEC_DIR>$clispec</CLICON_CLISPEC_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_CLI_MODE>example</CLICON_CLI_MODE>
<CLICON_SOCK>/usr/local/var/run/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_PIDFILE>/usr/local/var/run/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
<CLICON_NETCONF_CREATOR_ATTR>true</CLICON_NETCONF_CREATOR_ATTR>
</clixon-config>
EOF
cat <<EOF > $fyang
module clixon-example{
yang-version 1.1;
namespace "urn:example:clixon";
prefix ex;
container table {
list parameter{
key name;
leaf name{
type string;
}
leaf value{
type string;
}
}
}
}
EOF
new "test params: -f $cfg"
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -zf $cfg
if [ $? -ne 0 ]; then
err
fi
new "start backend -s init -f $cfg"
start_backend -s init -f $cfg
fi
new "wait backend 1"
wait_backend
conf="-d candidate -b $dir -y $fyang"
new "s1 add x"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><default-operation>none</default-operation><target><candidate/></target><config><table xmlns=\"urn:example:clixon\"><parameter nc:operation=\"create\" xmlns:nc=\"${BASENS}\" cl:creator=\"s1\" xmlns:cl=\"http://clicon.org/lib\"><name>x</name><value>foo</value></parameter></table></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "datastore get"
expectpart "$(sudo $clixon_util_xpath -f $dir/candidate_db -p /config/creators)" 0 "<creators xmlns=\"http://clicon.org/lib\"><creator><name>s1</name><path>/table/parameter\[name=\"x\"\]</path></creator></creators>"
new "rpc get-config"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "<table xmlns=\"urn:example:clixon\"><parameter><name>x</name><value>foo</value></parameter></table>" ""
# duplicate
new "s1 merge x"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><default-operation>none</default-operation><target><candidate/></target><config><table xmlns=\"urn:example:clixon\"><parameter nc:operation=\"merge\" xmlns:nc=\"${BASENS}\" cl:creator=\"s1\" xmlns:cl=\"http://clicon.org/lib\"><name>x</name><value>foo</value></parameter></table></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "datastore get"
expectpart "$(sudo $clixon_util_xpath -f $dir/candidate_db -p /config/creators)" 0 "<creators xmlns=\"http://clicon.org/lib\"><creator><name>s1</name><path>/table/parameter\[name=\"x\"\]</path></creator></creators>"
# New service
new "s2 merge x"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><default-operation>none</default-operation><target><candidate/></target><config><table xmlns=\"urn:example:clixon\"><parameter nc:operation=\"merge\" xmlns:nc=\"${BASENS}\" cl:creator=\"s2\" xmlns:cl=\"http://clicon.org/lib\"><name>x</name><value>foo</value></parameter></table></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "datastore get"
expectpart "$(sudo $clixon_util_xpath -f $dir/candidate_db -p /config/creators)" 0 "<creators xmlns=\"http://clicon.org/lib\"><creator><name>s1</name><path>/table/parameter\[name=\"x\"\]</path></creator><creator><name>s2</name><path>/table/parameter\[name=\"x\"\]</path></creator></creators>"
# New entry
new "s1 create y=bar"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><default-operation>none</default-operation><target><candidate/></target><config><table xmlns=\"urn:example:clixon\"><parameter nc:operation=\"create\" xmlns:nc=\"${BASENS}\" cl:creator=\"s1\" xmlns:cl=\"http://clicon.org/lib\"><name>y</name><value>bar</value></parameter></table></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "datastore get"
expectpart "$(sudo $clixon_util_xpath -f $dir/candidate_db -p /config/creators)" 0 "<creators xmlns=\"http://clicon.org/lib\"><creator><name>s1</name><path>/table/parameter\[name=\"x\"\]</path><path>/table/parameter\[name=\"y\"\]</path></creator><creator><name>s2</name><path>/table/parameter\[name=\"x\"\]</path></creator></creators>"
# To running
new "commit to running"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><commit/></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "datastore get running"
expectpart "$(sudo $clixon_util_xpath -f $dir/running_db -p /config/creators)" 0 "<creators xmlns=\"http://clicon.org/lib\"><creator><name>s1</name><path>/table/parameter\[name=\"x\"\]</path><path>/table/parameter\[name=\"y\"\]</path></creator><creator><name>s2</name><path>/table/parameter\[name=\"x\"\]</path></creator></creators>"
new "rpc get-config"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>" "<table xmlns=\"urn:example:clixon\"><parameter><name>x</name><value>foo</value></parameter><parameter><name>y</name><value>bar</value></parameter></table>" ""
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -zf $cfg
if [ $? -ne 0 ]; then
err
fi
fi
if [ $BE -ne 0 ]; then
new "start backend -s running -f $cfg"
start_backend -s running -f $cfg
fi
new "wait backend 2"
wait_backend
new "datastore get running"
expectpart "$(sudo $clixon_util_xpath -f $dir/running_db -p /config/creators)" 0 "<creators xmlns=\"http://clicon.org/lib\"><creator><name>s1</name><path>/table/parameter\[name=\"x\"\]</path><path>/table/parameter\[name=\"y\"\]</path></creator><creator><name>s2</name><path>/table/parameter\[name=\"x\"\]</path></creator></creators>"
new "rpc get-config"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>" "<table xmlns=\"urn:example:clixon\"><parameter><name>x</name><value>foo</value></parameter><parameter><name>y</name><value>bar</value></parameter></table>" ""
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -zf $cfg
if [ $? -ne 0 ]; then
err
fi
fi
rm -rf $dir
new "endtest"
endtest

View file

@ -51,12 +51,14 @@ module clixon-config {
revision 2024-01-01 { revision 2024-01-01 {
description description
"Released in Clixon 6.6"; "Makred as obsolete:
CLICON_NETCONF_CREATOR_ATTR
Released in Clixon 6.6";
} }
revision 2023-11-01 { revision 2023-11-01 {
description description
"Added options: "Added options:
CLICON_CREATOR_ATTR CLICON_NETCONF_CREATOR_ATTR
Released in Clixon 6.5"; Released in Clixon 6.5";
} }
revision 2023-05-01 { revision 2023-05-01 {
@ -596,7 +598,10 @@ module clixon-config {
If one such client/service is deleted, the object is deleted only if all services If one such client/service is deleted, the object is deleted only if all services
that created the object are deleted. that created the object are deleted.
The clixon controller uses this feature, but could in principle be used by other The clixon controller uses this feature, but could in principle be used by other
applications."; applications.
Marked as obsolete in 6.6 since creators attribute replaced by clixon-lib creators
config";
status obsolete;
} }
leaf CLICON_RESTCONF_API_ROOT { leaf CLICON_RESTCONF_API_ROOT {
type string; type string;

View file

@ -70,7 +70,7 @@ module clixon-lib {
revision 2024-01-01 { revision 2024-01-01 {
description description
"Moved container creators to grouping/uses "Moved container creators to grouping/uses and removed config false
Released in 6.6.0"; Released in 6.6.0";
} }
revision 2023-11-01 { revision 2023-11-01 {
@ -217,8 +217,7 @@ module clixon-lib {
} }
grouping clixon-creators{ grouping clixon-creators{
container creators{ container creators{
config false; description "Meta-data for creation of data objects.";
description "Meta-data for creator attribute.";
list creator { list creator {
key name; key name;
leaf name { leaf name {