XML creation and parse API changes

This commit is contained in:
Olof Hagsand 2017-12-09 14:14:40 +01:00
parent 056b5c97dd
commit 4742fde1e9
21 changed files with 309 additions and 258 deletions

View file

@ -296,7 +296,7 @@ rundb_main(clicon_handle h,
clicon_err(OE_UNIX, errno, "open(%s)", extraxml_file);
goto done;
}
if (clicon_xml_parse_file(fd, &xt, "</clicon>") < 0)
if (xml_parse_file(fd, &xt, "</clicon>") < 0)
goto done;
if ((xn = xml_child_i(xt, 0)) != NULL)
if (xmldb_put(h, "tmp", OP_MERGE, xn) < 0)
@ -442,7 +442,7 @@ load_extraxml(clicon_handle h,
clicon_err(OE_UNIX, errno, "open(%s)", filename);
goto done;
}
if (clicon_xml_parse_file(fd, "</config>", NULL, &xt) < 0)
if (xml_parse_file(fd, "</config>", NULL, &xt) < 0)
goto done;
/* Replace parent w first child */
if (xml_rootchild(xt, 0, &xt) < 0)
@ -827,7 +827,7 @@ main(int argc, char **argv)
if (xmldb_setopt(h, "yangspec", clicon_dbspec_yang(h)) < 0)
goto done;
if ((xml_cache = clicon_option_bool(h, "CLICON_XMLDB_CACHE")) >= 0)
if (xmldb_setopt(h, "xml_cache", (void*)xml_cache) < 0)
if (xmldb_setopt(h, "xml_cache", (void*)(intptr_t)xml_cache) < 0)
goto done;
/* If startup mode is not defined, eg via OPTION or -s, assume old method */
startup_mode = clicon_startup_mode(h);

View file

@ -746,7 +746,7 @@ load_config_file(clicon_handle h,
clicon_err(OE_UNIX, errno, "%s: open(%s)", __FUNCTION__, filename);
goto done;
}
if (clicon_xml_parse_file(fd, "</clicon>", NULL, &xt) < 0)
if (xml_parse_file(fd, "</clicon>", NULL, &xt) < 0)
goto done;
if (xt == NULL)
goto done;

View file

@ -190,7 +190,7 @@ netconf_output(int s,
clicon_debug(1, "SEND %s", msg);
if (debug > 1){ /* XXX: below only works to stderr, clicon_debug may log to syslog */
cxobj *xt = NULL;
if (clicon_xml_parse_str(buf, NULL, &xt) == 0){
if (xml_parse_string(buf, NULL, &xt) == 0){
clicon_xml2file(stderr, xml_child_i(xt, 0), 0, 0);
fprintf(stderr, "\n");
xml_free(xt);

View file

@ -98,7 +98,7 @@ process_incoming_packet(clicon_handle h,
}
str = str0;
/* Parse incoming XML message */
if (clicon_xml_parse_str(str, NULL, &xreq) < 0){
if (xml_parse_string(str, NULL, &xreq) < 0){
if ((cbret = cbuf_new()) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"

View file

@ -198,6 +198,9 @@ catch:
}
/*! See if there is any callback registered for this tag
*
* Look for local (client-side) netconf plugins. This feature may no
* longer be necessary as generic RPC:s should be handled by backend.
*
* @param[in] h clicon handle
* @param[in] xn Sub-tree (under xorig) at child of rpc: <rpc><xn></rpc>.
@ -214,13 +217,7 @@ netconf_plugin_callbacks(clicon_handle h,
{
int retval = -1;
netconf_reg_t *nreg;
yang_spec *yspec = NULL; /* application yspec */
yang_stmt *yrpc;
yang_stmt *yinput;
yang_stmt *youtput;
cxobj *xoutput;
cbuf *cb = NULL;
if (deps != NULL){
nreg = deps;
do {
@ -233,70 +230,8 @@ netconf_plugin_callbacks(clicon_handle h,
nreg = NEXTQ(netconf_reg_t *, nreg);
} while (nreg != deps);
}
/* First check system / netconf RPC:s */
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, 0, "cbuf_new");
goto done;
}
/* create absolute path */
if (xml_namespace(xn))
cprintf(cb, "/%s:%s", xml_namespace(xn), xml_name(xn));
else
cprintf(cb, "/nc:%s", xml_name(xn)); /* Hardcoded for netconf */
/* Find yang rpc statement, return yang rpc statement if found */
if (yrpc == NULL){
/* Then check application RPC */
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_YANG, ENOENT, "No yang spec");
goto done;
}
cbuf_reset(cb);
if (xml_namespace(xn))
cprintf(cb, "/%s:%s", xml_namespace(xn), xml_name(xn));
else
cprintf(cb, "/%s", xml_name(xn)); /* XXX not accepdted by below */
/* Find yang rpc statement, return yang rpc statement if found */
if (yang_abs_schema_nodeid(yspec, cbuf_get(cb), &yrpc) < 0)
goto done;
}
/* Check if found */
if (yrpc != NULL){
if ((yinput = yang_find((yang_node*)yrpc, Y_INPUT, NULL)) != NULL){
xml_spec_set(xn, yinput); /* needed for xml_spec_populate */
if (xml_apply(xn, CX_ELMNT, xml_spec_populate, yinput) < 0)
goto done;
if (xml_apply(xn, CX_ELMNT,
(xml_applyfn_t*)xml_yang_validate_all, NULL) < 0)
goto done;
if (xml_yang_validate_add(xn, NULL) < 0)
goto done;
}
/*
* 1. Check xn arguments with input statement.
* 2. Send to backend as clicon_msg-encode()
* 3. In backend to similar but there call actual backend
*/
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
goto done;
/* Sanity check of outgoing XML */
if ((youtput = yang_find((yang_node*)yrpc, Y_OUTPUT, NULL)) != NULL){
xoutput=xpath_first(*xret, "/");
xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, youtput) < 0)
goto done;
if (xml_apply(xoutput, CX_ELMNT,
(xml_applyfn_t*)xml_yang_validate_all, NULL) < 0)
goto done;
if (xml_yang_validate_add(xoutput, NULL) < 0)
goto done;
}
retval = 1; /* handled by callback */
goto done;
}
retval = 0;
done:
if (cb)
cbuf_free(cb);
return retval;
}

View file

@ -135,7 +135,7 @@ netconf_get_config(clicon_handle h,
cxobj *xconf;
if ((source = netconf_get_target(xn, "source")) == NULL){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -163,7 +163,7 @@ netconf_get_config(clicon_handle h,
/* xml_filter removes parts of xml tree not matching */
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
xml_filter(xfilterconf, xconf) < 0){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
@ -173,7 +173,7 @@ netconf_get_config(clicon_handle h,
}
}
else{
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
@ -241,7 +241,7 @@ get_edit_opts(cxobj *xn,
retval = 1; /* hunky dory */
return retval;
parerr: /* parameter error, xret set */
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -317,7 +317,7 @@ netconf_edit_config(clicon_handle h,
/* must have target, and it should be candidate */
if ((target = netconf_get_target(xn, "target")) == NULL ||
strcmp(target, "candidate")){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -329,7 +329,7 @@ netconf_edit_config(clicon_handle h,
if ((xfilter = xpath_first(xn, "filter")) != NULL) {
if ((ftype = xml_find_value(xfilter, "type")) != NULL)
if (strcmp(ftype,"restconf")){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -339,7 +339,7 @@ netconf_edit_config(clicon_handle h,
}
if ((x = xpath_first(xn, "default-operation")) != NULL){
if (xml_operation(xml_body(x), &operation) < 0){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -353,7 +353,7 @@ netconf_edit_config(clicon_handle h,
goto ok;
/* not supported opts */
if (testopt!=TEST_THEN_SET || erropt!=STOP_ON_ERROR){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-not-supported</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -403,7 +403,7 @@ netconf_copy_config(clicon_handle h,
char *target; /* filenames */
if ((source = netconf_get_target(xn, "source")) == NULL){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -412,7 +412,7 @@ netconf_copy_config(clicon_handle h,
goto ok;
}
if ((target = netconf_get_target(xn, "target")) == NULL){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -450,7 +450,7 @@ netconf_delete_config(clicon_handle h,
if ((target = netconf_get_target(xn, "target")) == NULL ||
strcmp(target, "running")==0){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -486,7 +486,7 @@ netconf_lock(clicon_handle h,
char *target;
if ((target = netconf_get_target(xn, "target")) == NULL){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -566,7 +566,7 @@ netconf_get(clicon_handle h,
/* xml_filter removes parts of xml tree not matching */
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
xml_filter(xfilterconf, xconf) < 0){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
@ -576,7 +576,7 @@ netconf_get(clicon_handle h,
}
}
else{
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
@ -627,7 +627,7 @@ netconf_kill_session(clicon_handle h,
cxobj *xs;
if ((xs = xpath_first(xn, "//session-id")) == NULL){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -658,7 +658,7 @@ netconf_validate(clicon_handle h,
char *target;
if ((target = netconf_get_target(xn, "source")) == NULL){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
@ -826,7 +826,7 @@ netconf_create_subscription(clicon_handle h,
if ((xfilter = xpath_first(xn, "//filter")) != NULL){
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
if (strcmp(ftype, "xpath") != 0){
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>application</error-type>"
"<error-severity>error</error-severity>"
@ -850,6 +850,92 @@ netconf_create_subscription(clicon_handle h,
return retval;
}
/*! See if there is any callback registered for this tag
*
* @param[in] h clicon handle
* @param[in] xn Sub-tree (under xorig) at child of rpc: <rpc><xn></rpc>.
* @param[out] xret Return XML, error or OK
*
* @retval -1 Error
* @retval 0 OK, not found handler.
* @retval 1 OK, handler called
*/
static int
netconf_application_rpc(clicon_handle h,
cxobj *xn,
cxobj **xret)
{
int retval = -1;
yang_spec *yspec = NULL; /* application yspec */
yang_stmt *yrpc = NULL;
yang_stmt *yinput;
yang_stmt *youtput;
cxobj *xoutput;
cbuf *cb = NULL;
/* First check system / netconf RPC:s */
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, 0, "cbuf_new");
goto done;
}
/* Find yang rpc statement, return yang rpc statement if found
Check application RPC */
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_YANG, ENOENT, "No yang spec");
goto done;
}
cbuf_reset(cb);
// if (xml_namespace(xn))
cprintf(cb, "/%s:%s", xml_namespace(xn), xml_name(xn));
// else
// cprintf(cb, "/%s", xml_name(xn)); /* XXX not accepdted by below */
/* Find yang rpc statement, return yang rpc statement if found */
if (yang_abs_schema_nodeid(yspec, cbuf_get(cb), &yrpc) < 0)
goto done;
/* Check if found */
if (yrpc != NULL){
if ((yinput = yang_find((yang_node*)yrpc, Y_INPUT, NULL)) != NULL){
xml_spec_set(xn, yinput); /* needed for xml_spec_populate */
if (xml_apply(xn, CX_ELMNT, xml_spec_populate, yinput) < 0)
goto done;
if (xml_apply(xn, CX_ELMNT,
(xml_applyfn_t*)xml_yang_validate_all, NULL) < 0)
goto done;
if (xml_yang_validate_add(xn, NULL) < 0)
goto done;
}
/*
* 1. Check xn arguments with input statement.
* 2. Send to backend as clicon_msg-encode()
* 3. In backend to similar but there call actual backend
*/
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
goto done;
/* Sanity check of outgoing XML */
if ((youtput = yang_find((yang_node*)yrpc, Y_OUTPUT, NULL)) != NULL){
xoutput=xpath_first(*xret, "/");
xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, youtput) < 0)
goto done;
if (xml_apply(xoutput, CX_ELMNT,
(xml_applyfn_t*)xml_yang_validate_all, NULL) < 0)
goto done;
if (xml_yang_validate_add(xoutput, NULL) < 0)
goto done;
}
retval = 1; /* handled by callback */
goto done;
}
retval = 0;
done:
if (cb)
cbuf_free(cb);
return retval;
}
/*! The central netconf rpc dispatcher. Look at first tag and dispach to sub-functions.
* Call plugin handler if tag not found. If not handled by any handler, return
* error.
@ -932,10 +1018,16 @@ netconf_rpc_dispatch(clicon_handle h,
}
/* Others */
else {
/* Look for local (client-side) netconf plugins. This feature may no
* longer be necessary as generic RPC:s should be handled by backend.
*/
if ((retval = netconf_plugin_callbacks(h, xe, xret)) < 0)
goto done;
if (retval == 0)
if ((retval = netconf_application_rpc(h, xe, xret)) < 0)
goto done;
if (retval == 0){ /* not handled by callback */
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>rpc</error-type>"
"<error-severity>error</error-severity>"

View file

@ -376,7 +376,7 @@ api_data_post(clicon_handle h,
goto done;
/* Parse input data as json or xml into xml */
if (parse_xml){
if (clicon_xml_parse_str(data, NULL, &xdata) < 0){
if (xml_parse_string(data, NULL, &xdata) < 0){
clicon_debug(1, "%s json parse fail: %s", __FUNCTION__, data);
goto done;
}
@ -495,7 +495,7 @@ api_data_put(clicon_handle h,
goto done;
/* Parse input data as json or xml into xml */
if (parse_xml){
if (clicon_xml_parse_str(data, NULL, &xdata) < 0){
if (xml_parse_string(data, NULL, &xdata) < 0){
clicon_debug(1, "%s json parse fail: %s", __FUNCTION__, data);
goto done;
}
@ -729,7 +729,7 @@ api_operation_post(clicon_handle h,
if (data && strlen(data)){
/* Parse input data as json or xml into xml */
if (parse_xml){
if (clicon_xml_parse_str(data, NULL, &xdata) < 0){
if (xml_parse_string(data, NULL, &xdata) < 0){
clicon_debug(1, "%s json parse fail: %s", __FUNCTION__, data);
goto done;
}