remove move end transaction
This commit is contained in:
parent
662d6b0a3f
commit
d2531421f2
5 changed files with 206 additions and 77 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -1,6 +1,6 @@
|
||||||
# Clixon Changelog
|
# Clixon Changelog
|
||||||
|
|
||||||
* [4.4.0](#440) Expected: March 2020
|
* [4.4.0](#440) Expected: April 2020
|
||||||
* [4.3.0](#430) 1 January 2020
|
* [4.3.0](#430) 1 January 2020
|
||||||
* [4.3.3](#433)
|
* [4.3.3](#433)
|
||||||
* [4.3.2](#432)
|
* [4.3.2](#432)
|
||||||
|
|
@ -21,9 +21,9 @@
|
||||||
* [3.3.1](#331) June 7 2017
|
* [3.3.1](#331) June 7 2017
|
||||||
|
|
||||||
## 4.4.0
|
## 4.4.0
|
||||||
Expected: March 2020
|
Expected: April 2020
|
||||||
|
|
||||||
This release has focussed on refactoring and bugfixing. Lots of
|
This release focusses on refactoring and bugfixing. Lots of
|
||||||
changes to basic XML/YANG/RESTCONF code, including a tighter XML/YANG
|
changes to basic XML/YANG/RESTCONF code, including a tighter XML/YANG
|
||||||
binding. Memory profiling and new buffer growth management. New
|
binding. Memory profiling and new buffer growth management. New
|
||||||
features include optimized search functions and a repair callback.
|
features include optimized search functions and a repair callback.
|
||||||
|
|
@ -43,7 +43,7 @@ features include optimized search functions and a repair callback.
|
||||||
* For more info, see docs at [paths](https://clixon-docs.readthedocs.io/en/latest/paths.html) and
|
* For more info, see docs at [paths](https://clixon-docs.readthedocs.io/en/latest/paths.html) and
|
||||||
[search](https://clixon-docs.readthedocs.io/en/latest/xml.html#searching-in-xml)
|
[search](https://clixon-docs.readthedocs.io/en/latest/xml.html#searching-in-xml)
|
||||||
|
|
||||||
### API changes on existing protocol/config features
|
### API changes on existing protocol/config features (You may have have to change how you use Clixon)
|
||||||
* State data is now ordered-by system for performance reasons. For example, alphabetically for strings and numeric for integers
|
* State data is now ordered-by system for performance reasons. For example, alphabetically for strings and numeric for integers
|
||||||
* Controlled by compile-time option `STATE_ORDERED_BY_SYSTEM`
|
* Controlled by compile-time option `STATE_ORDERED_BY_SYSTEM`
|
||||||
* Obsolete configuration options present in clixon configuration file will cause clixon application to exit at startup.
|
* Obsolete configuration options present in clixon configuration file will cause clixon application to exit at startup.
|
||||||
|
|
@ -78,7 +78,7 @@ features include optimized search functions and a repair callback.
|
||||||
* `xml_new()` changed from `xml_new(name, xp, ys)` to `xml_new(name, xp, type)`
|
* `xml_new()` changed from `xml_new(name, xp, ys)` to `xml_new(name, xp, type)`
|
||||||
* If you have used, `ys`, add `xml_spec_set(x, ys)` after the statement
|
* If you have used, `ys`, add `xml_spec_set(x, ys)` after the statement
|
||||||
* If you have `xml_type_set(x, TYPE)` after the statement, you can remove it and set it directly as: `xml_new(name, xp, TYPE)`
|
* If you have `xml_type_set(x, TYPE)` after the statement, you can remove it and set it directly as: `xml_new(name, xp, TYPE)`
|
||||||
* `xml_type_set()`has been removed in the API. The type must be set at creation timw with `xml_new`
|
* `xml_type_set()` has been removed in the API. The type must be set at creation time with `xml_new`
|
||||||
* `clicon_rpc_generate_error()` renamed to `clixon_netconf_error()` and added a category parameter
|
* `clicon_rpc_generate_error()` renamed to `clixon_netconf_error()` and added a category parameter
|
||||||
* All uses of `api_path2xpath_cvv()` should be replaced by `api_path2xpath()`
|
* All uses of `api_path2xpath_cvv()` should be replaced by `api_path2xpath()`
|
||||||
* `api_path2xpath()` added an `xerr` argument.
|
* `api_path2xpath()` added an `xerr` argument.
|
||||||
|
|
|
||||||
|
|
@ -349,30 +349,6 @@ startup_commit(clicon_handle h,
|
||||||
/* 8. Call plugin transaction commit callbacks */
|
/* 8. Call plugin transaction commit callbacks */
|
||||||
if (plugin_transaction_commit(h, td) < 0)
|
if (plugin_transaction_commit(h, td) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#ifdef MOVE_TRANS_END
|
|
||||||
/* 10. Call plugin transaction end callbacks */
|
|
||||||
plugin_transaction_end(h, td);
|
|
||||||
|
|
||||||
/* Clear cached trees from default values and marking */
|
|
||||||
if (xmldb_get0_clear(h, td->td_target) < 0)
|
|
||||||
goto done;
|
|
||||||
/* [Delete and] create running db */
|
|
||||||
if (xmldb_exists(h, "running") == 1){
|
|
||||||
if (xmldb_delete(h, "running") != 0 && errno != ENOENT)
|
|
||||||
goto done;;
|
|
||||||
}
|
|
||||||
if (xmldb_create(h, "running") < 0)
|
|
||||||
goto done;
|
|
||||||
/* 9, write (potentially modified) tree to running
|
|
||||||
* XXX note here startup is copied to candidate, which may confuse everything
|
|
||||||
* XXX default values are overwritten
|
|
||||||
*/
|
|
||||||
if ((ret = xmldb_put(h, "running", OP_REPLACE, td->td_target,
|
|
||||||
clicon_username_get(h), cbret)) < 0)
|
|
||||||
goto done;
|
|
||||||
if (ret == 0)
|
|
||||||
goto fail;
|
|
||||||
#else
|
|
||||||
/* Clear cached trees from default values and marking */
|
/* Clear cached trees from default values and marking */
|
||||||
if (xmldb_get0_clear(h, td->td_target) < 0)
|
if (xmldb_get0_clear(h, td->td_target) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -395,7 +371,6 @@ startup_commit(clicon_handle h,
|
||||||
goto fail;
|
goto fail;
|
||||||
/* 10. Call plugin transaction end callbacks */
|
/* 10. Call plugin transaction end callbacks */
|
||||||
plugin_transaction_end(h, td);
|
plugin_transaction_end(h, td);
|
||||||
#endif /* MOVE_TRANS_END */
|
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
if (td){
|
if (td){
|
||||||
|
|
@ -566,30 +541,6 @@ candidate_commit(clicon_handle h,
|
||||||
if (plugin_transaction_commit(h, td) < 0)
|
if (plugin_transaction_commit(h, td) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
#ifdef MOVE_TRANS_END
|
|
||||||
/* 9. Call plugin transaction end callbacks */
|
|
||||||
plugin_transaction_end(h, td);
|
|
||||||
|
|
||||||
/* Clear cached trees from default values and marking */
|
|
||||||
if (xmldb_get0_clear(h, td->td_target) < 0)
|
|
||||||
goto done;
|
|
||||||
if (xmldb_get0_clear(h, td->td_src) < 0)
|
|
||||||
goto done;
|
|
||||||
/* 8. Success: Copy candidate to running
|
|
||||||
*/
|
|
||||||
if (xmldb_copy(h, candidate, "running") < 0)
|
|
||||||
goto done;
|
|
||||||
/* Here pointers to old (source) tree are obsolete */
|
|
||||||
if (td->td_dvec){
|
|
||||||
td->td_dlen = 0;
|
|
||||||
free(td->td_dvec);
|
|
||||||
td->td_dvec = NULL;
|
|
||||||
}
|
|
||||||
if (td->td_scvec){
|
|
||||||
free(td->td_scvec);
|
|
||||||
td->td_scvec = NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Clear cached trees from default values and marking */
|
/* Clear cached trees from default values and marking */
|
||||||
if (xmldb_get0_clear(h, td->td_target) < 0)
|
if (xmldb_get0_clear(h, td->td_target) < 0)
|
||||||
|
|
@ -623,8 +574,6 @@ candidate_commit(clicon_handle h,
|
||||||
|
|
||||||
/* 9. Call plugin transaction end callbacks */
|
/* 9. Call plugin transaction end callbacks */
|
||||||
plugin_transaction_end(h, td);
|
plugin_transaction_end(h, td);
|
||||||
|
|
||||||
#endif /* MOVE_TRANS_END */
|
|
||||||
|
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
|
@ -825,17 +774,7 @@ from_client_validate(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
#ifdef MOVE_TRANS_END
|
|
||||||
/* Call plugin transaction end callbacks */
|
|
||||||
plugin_transaction_end(h, td);
|
|
||||||
/* Clear cached trees from default values and marking */
|
|
||||||
if (xmldb_get0_clear(h, td->td_src) < 0 ||
|
|
||||||
xmldb_get0_clear(h, td->td_target) < 0){
|
|
||||||
plugin_transaction_abort(h, td);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
|
||||||
#else /* MOVE_TRANS_END */
|
|
||||||
if (xmldb_get0_clear(h, td->td_src) < 0 ||
|
if (xmldb_get0_clear(h, td->td_src) < 0 ||
|
||||||
xmldb_get0_clear(h, td->td_target) < 0){
|
xmldb_get0_clear(h, td->td_target) < 0){
|
||||||
plugin_transaction_abort(h, td);
|
plugin_transaction_abort(h, td);
|
||||||
|
|
@ -853,7 +792,6 @@ from_client_validate(clicon_handle h,
|
||||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||||
/* Call plugin transaction end callbacks */
|
/* Call plugin transaction end callbacks */
|
||||||
plugin_transaction_end(h, td);
|
plugin_transaction_end(h, td);
|
||||||
#endif /* MOVE_TRANS_END */
|
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
|
||||||
|
|
@ -88,14 +88,6 @@
|
||||||
*/
|
*/
|
||||||
#define XMLDB_CONFIG_HACK
|
#define XMLDB_CONFIG_HACK
|
||||||
|
|
||||||
/*! Ensure target tree is complete when transaction end is called.
|
|
||||||
* This may mean that the call to plugin_transaction_end is done later
|
|
||||||
* and/or that cleaning of transaction src/target trees are made later
|
|
||||||
* clixon-4.4
|
|
||||||
* note: a test in test_transaction.sh does not work
|
|
||||||
*/
|
|
||||||
#define MOVE_TRANS_END
|
|
||||||
|
|
||||||
/*! Let state data be ordered-by system
|
/*! Let state data be ordered-by system
|
||||||
* RFC 7950 is cryptic about this
|
* RFC 7950 is cryptic about this
|
||||||
* It says in 7.7.7:
|
* It says in 7.7.7:
|
||||||
|
|
|
||||||
199
test/test_json_null.sh
Executable file
199
test/test_json_null.sh
Executable file
|
|
@ -0,0 +1,199 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Test: JSON empty/null values. See RFC7951
|
||||||
|
# tests include:
|
||||||
|
# - parsing in XML, output in JSON
|
||||||
|
# - parsing in JSON, output in JSON
|
||||||
|
# - parsing in JSON, output in XML?
|
||||||
|
#
|
||||||
|
# Magic line must be first in script (see README.md)
|
||||||
|
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||||
|
|
||||||
|
: ${clixon_util_json:=clixon_util_json}
|
||||||
|
: ${clixon_util_xml:=clixon_util_xml}
|
||||||
|
|
||||||
|
fyang=$dir/json.yang
|
||||||
|
cat <<EOF > $fyang
|
||||||
|
module json{
|
||||||
|
prefix j;
|
||||||
|
namespace "urn:example:clixon";
|
||||||
|
container leafs{
|
||||||
|
leaf a{
|
||||||
|
type int32;
|
||||||
|
}
|
||||||
|
leaf b{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf c{
|
||||||
|
type boolean;
|
||||||
|
}
|
||||||
|
leaf d{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container leaf-lists{
|
||||||
|
leaf-list a{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
leaf-list b{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container containers{
|
||||||
|
presence true;
|
||||||
|
container a{
|
||||||
|
presence true;
|
||||||
|
leaf b {
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container anys{
|
||||||
|
anydata a;
|
||||||
|
anyxml b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
new "test params: -y $fyang"
|
||||||
|
|
||||||
|
# Leafs
|
||||||
|
XML='<leafs xmlns="urn:example:clixon"><a>0</a><b></b><c>false</c><d></d></leafs>'
|
||||||
|
JSON='{"json:leafs":{"a":0,"b":"","c":false,"d":[null]}}'
|
||||||
|
|
||||||
|
new "leafs xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
new "leafs json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovJjy $fyang" 0 "$JSON" "$JSON"
|
||||||
|
|
||||||
|
new "leafs json to xml"
|
||||||
|
expecteofx "$clixon_util_xml -ovJy $fyang" 0 "$JSON" "$XML"
|
||||||
|
|
||||||
|
# Leaf-lists single
|
||||||
|
XML='<leaf-lists xmlns="urn:example:clixon"><a></a><b></b></leaf-lists>'
|
||||||
|
JSON='{"json:leaf-lists":{"a":[null],"b":""}}'
|
||||||
|
|
||||||
|
new "leaf-list single xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
new "leaf-list single json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjJy $fyang" 0 "$JSON" "$JSON"
|
||||||
|
|
||||||
|
new "leaf-list single json to xml"
|
||||||
|
expecteofx "$clixon_util_xml -ovJy $fyang" 0 "$JSON" "$XML"
|
||||||
|
|
||||||
|
# Leaf-lists multiple
|
||||||
|
XML='<leaf-lists xmlns="urn:example:clixon"><a></a><a></a><b></b><b></b><b>null</b></leaf-lists>'
|
||||||
|
JSON='{"json:leaf-lists":{"a":[[null],[null]],"b":["","","null"]}}'
|
||||||
|
|
||||||
|
new "leaf-list multiple xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
new "leaf-list multiple json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjJy $fyang" 0 "$JSON" "$JSON"
|
||||||
|
|
||||||
|
new "leaf-list multiple json to xml"
|
||||||
|
expecteofx "$clixon_util_xml -ovJy $fyang" 0 "$JSON" "$XML"
|
||||||
|
|
||||||
|
# Empty container
|
||||||
|
XML='<containers xmlns="urn:example:clixon"><a/></containers>'
|
||||||
|
JSON='{"json:containers":{"a":{}}}'
|
||||||
|
|
||||||
|
new "empty container xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
new "empty container json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjJy $fyang" 0 "$JSON" "$JSON"
|
||||||
|
|
||||||
|
new "empty container json to xml"
|
||||||
|
expecteofx "$clixon_util_xml -ovJy $fyang" 0 "$JSON" "$XML"
|
||||||
|
|
||||||
|
# Empty container whitespace
|
||||||
|
XML='<containers xmlns="urn:example:clixon"><a> </a></containers>'
|
||||||
|
JSON='{"json:containers":{"a":{}}}'
|
||||||
|
|
||||||
|
new "empty container whitespace xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
# container empty leaf
|
||||||
|
XML='<containers xmlns="urn:example:clixon"><a><b></b></a></containers>'
|
||||||
|
JSON='{"json:containers":{"a":{"b":[null]}}}'
|
||||||
|
|
||||||
|
new "container empty leaf xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
new "container empty leaf json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjJy $fyang" 0 "$JSON" "$JSON"
|
||||||
|
|
||||||
|
new "container empty leaf json to xml"
|
||||||
|
expecteofx "$clixon_util_xml -ovJy $fyang" 0 "$JSON" "$XML"
|
||||||
|
|
||||||
|
# anydata
|
||||||
|
# An anydata instance is encoded in the same way as a container, as a name/object pair
|
||||||
|
XML='<anys xmlns="urn:example:clixon"><a/></anys>'
|
||||||
|
JSON='{"json:anys":{"a":{}}}'
|
||||||
|
|
||||||
|
new "anydata xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
new "anydata json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjJy $fyang" 0 "$JSON" "$JSON"
|
||||||
|
|
||||||
|
new "anydata json to xml"
|
||||||
|
expecteofx "$clixon_util_xml -ovJy $fyang" 0 "$JSON" "$XML"
|
||||||
|
|
||||||
|
# anydata
|
||||||
|
XML='<anys xmlns="urn:example:clixon"><a><c/><d/></a></anys>'
|
||||||
|
JSON='{"json:anys":{"a":{"c":{},"d":{}}}}'
|
||||||
|
|
||||||
|
new "anydata w empty node xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
new "anydata w empty node json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjJy $fyang" 0 "$JSON" "$JSON"
|
||||||
|
|
||||||
|
new "anydata w empty node json to xml"
|
||||||
|
expecteofx "$clixon_util_xml -ovJy $fyang" 0 "$JSON" "$XML"
|
||||||
|
|
||||||
|
# Anyxml
|
||||||
|
XML='<anys xmlns="urn:example:clixon"><b/></anys>'
|
||||||
|
JSON='{"json:anys":{"b":{}}}'
|
||||||
|
|
||||||
|
new "anyxml xml to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjy $fyang" 0 "$XML" "$JSON"
|
||||||
|
|
||||||
|
new "anyxml json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovjJy $fyang" 0 "$JSON" "$JSON"
|
||||||
|
|
||||||
|
new "anyxml json to xml"
|
||||||
|
expecteofx "$clixon_util_xml -ovJy $fyang" 0 "$JSON" "$XML"
|
||||||
|
|
||||||
|
# JSON wrong in?
|
||||||
|
# XXX: maybe this should give error?
|
||||||
|
JSON='{"json:leafs":{"b":null}}'
|
||||||
|
JSON2='{"json:leafs":{"b":""}}'
|
||||||
|
new "leafs null in json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovJjy $fyang" 0 "$JSON" "$JSON2"
|
||||||
|
|
||||||
|
# XXX: maybe this should give error?
|
||||||
|
JSON='{"json:leafs":{"b":[null]}}'
|
||||||
|
JSON2='{"json:leafs":{"b":""}}'
|
||||||
|
new "leafs [null] in json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovJjy $fyang" 0 "$JSON" "$JSON2"
|
||||||
|
|
||||||
|
# XXX: maybe this should give error?
|
||||||
|
JSON='{"json:leafs":{"d":null}}'
|
||||||
|
JSON2='{"json:leafs":{"d":[null]}}'
|
||||||
|
new "leafs null in json to json"
|
||||||
|
expecteofx "$clixon_util_xml -ovJjy $fyang" 0 "$JSON" "$JSON2"
|
||||||
|
|
||||||
|
JSON='{"json:leafs":{"d":""}}'
|
||||||
|
JSON2='{"json:leafs":{"d":[null]}}'
|
||||||
|
new "leafs \"\" in json to json should give error"
|
||||||
|
expecteofx "$clixon_util_xml -ovJjy $fyang" 255 "$JSON" "" 2> /dev/null
|
||||||
|
|
||||||
|
rm -rf $dir
|
||||||
|
|
||||||
|
# unset conditional parameters
|
||||||
|
unset clixon_util_json
|
||||||
|
unset clixon_util_xml
|
||||||
|
|
@ -277,7 +277,7 @@ done
|
||||||
checklog "$nr main_end add: <d>0</d>" $line
|
checklog "$nr main_end add: <d>0</d>" $line
|
||||||
let line++
|
let line++
|
||||||
# This check does not work if MOVE_TRANS_END is set
|
# This check does not work if MOVE_TRANS_END is set
|
||||||
#checklog "$nr main_end change: <b>42</b>" $line
|
checklog "$nr main_end change: <b>42</b>" $line
|
||||||
let line+=3 # skip nacm
|
let line+=3 # skip nacm
|
||||||
|
|
||||||
let nr++
|
let nr++
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue