* Major rewrite of event streams
* If you used old event callbacks API, you need to switch to the streams API
* See clixon_stream.[ch]
* Old streams API which needs to be removed include:
* clicon_log_register_callback()
* subscription_add() --> stream_register()
* backend_notify() and backend_notify_xml() - use stream_notify() instead
* Example uses "NETCONF" stream instead of "ROUTING"
* Added timeout option -t for clixon_netconf - quit after max time.
This commit is contained in:
parent
d7fbe75c9e
commit
98f3cd0e32
31 changed files with 597 additions and 635 deletions
|
|
@ -71,7 +71,7 @@
|
|||
#include "netconf_rpc.h"
|
||||
|
||||
/* Command line options to be passed to getopt(3) */
|
||||
#define NETCONF_OPTS "hDf:l:qa:u:d:y:U:"
|
||||
#define NETCONF_OPTS "hD:f:l:qa:u:d:y:U:t:"
|
||||
|
||||
#define NETCONF_LOGFILE "/tmp/clixon_netconf.log"
|
||||
|
||||
|
|
@ -284,6 +284,13 @@ netconf_terminate(clicon_handle h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
timeout_fn(int s,
|
||||
void *arg)
|
||||
{
|
||||
clicon_err(OE_EVENTS, ETIME, "User request timeout");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*! Usage help routine
|
||||
* @param[in] h Clicon handle
|
||||
|
|
@ -305,7 +312,8 @@ usage(clicon_handle h,
|
|||
"\t-d <dir>\tSpecify netconf plugin directory dir (default: %s)\n"
|
||||
|
||||
"\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n"
|
||||
"\t-U <user>\tOver-ride unix user with a pseudo user for NACM.\n",
|
||||
"\t-U <user>\tOver-ride unix user with a pseudo user for NACM.\n"
|
||||
"\t-t <sec>\tTimeout in seconds. Quit after this time.\n",
|
||||
argv0,
|
||||
clicon_netconf_dir(h)
|
||||
);
|
||||
|
|
@ -324,12 +332,13 @@ main(int argc,
|
|||
char *dir;
|
||||
int logdst = CLICON_LOG_STDERR;
|
||||
struct passwd *pw;
|
||||
|
||||
/* In the startup, logs to stderr & debug flag set later */
|
||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||
struct timeval tv = {0,}; /* timeout */
|
||||
|
||||
/* Create handle */
|
||||
if ((h = clicon_handle_init()) == NULL)
|
||||
return -1;
|
||||
/* In the startup, logs to stderr & debug flag set later */
|
||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||
|
||||
/* Set username to clicon handle. Use in all communication to backend */
|
||||
if ((pw = getpwuid(getuid())) == NULL){
|
||||
|
|
@ -338,7 +347,6 @@ main(int argc,
|
|||
}
|
||||
if (clicon_username_set(h, pw->pw_name) < 0)
|
||||
goto done;
|
||||
|
||||
while ((c = getopt(argc, argv, NETCONF_OPTS)) != -1)
|
||||
switch (c) {
|
||||
case 'h' : /* help */
|
||||
|
|
@ -362,6 +370,7 @@ main(int argc,
|
|||
goto done;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Logs, error and debug to stderr or syslog, set debug level
|
||||
*/
|
||||
|
|
@ -408,6 +417,10 @@ main(int argc,
|
|||
if (clicon_username_set(h, optarg) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case 't': /* timeout in seconds */
|
||||
tv.tv_sec = atoi(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(h, argv[0]);
|
||||
break;
|
||||
|
|
@ -440,6 +453,13 @@ main(int argc,
|
|||
goto done;
|
||||
if (debug)
|
||||
clicon_option_dump(h, debug);
|
||||
if (tv.tv_sec || tv.tv_usec){
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
timeradd(&t, &tv, &t);
|
||||
if (event_reg_timeout(t, timeout_fn, NULL, "timeout") < 0)
|
||||
goto done;
|
||||
}
|
||||
if (event_loop() < 0)
|
||||
goto done;
|
||||
done:
|
||||
|
|
|
|||
|
|
@ -733,20 +733,14 @@ static int
|
|||
netconf_notification_cb(int s,
|
||||
void *arg)
|
||||
{
|
||||
cxobj *xfilter = (cxobj *)arg;
|
||||
char *selector;
|
||||
struct clicon_msg *reply = NULL;
|
||||
int eof;
|
||||
char *event = NULL;
|
||||
int retval = -1;
|
||||
cbuf *cb;
|
||||
cxobj *xe = NULL; /* event xml */
|
||||
cxobj *xn = NULL; /* event xml */
|
||||
cxobj *xt = NULL; /* top xml */
|
||||
|
||||
if (0){
|
||||
fprintf(stderr, "%s\n", __FUNCTION__); /* debug */
|
||||
xml_print(stderr, xfilter); /* debug */
|
||||
}
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
/* get msg (this is the reason this function is called) */
|
||||
if (clicon_msg_rcv(s, &reply, &eof) < 0)
|
||||
goto done;
|
||||
|
|
@ -756,31 +750,20 @@ netconf_notification_cb(int s,
|
|||
close(s);
|
||||
errno = ESHUTDOWN;
|
||||
event_unreg_fd(s, netconf_notification_cb);
|
||||
if (xfilter)
|
||||
xml_free(xfilter);
|
||||
goto done;
|
||||
}
|
||||
if (clicon_msg_decode(reply, &xt) < 0)
|
||||
goto done;
|
||||
if ((xe = xpath_first(xt, "//event")) != NULL)
|
||||
event = xml_body(xe);
|
||||
|
||||
/* parse event */
|
||||
if (0){ /* XXX CLICON events are not xml */
|
||||
/* find and apply filter */
|
||||
if ((selector = xml_find_value(xfilter, "select")) == NULL)
|
||||
goto done;
|
||||
if (xpath_first(xe, "%s", selector) == NULL) {
|
||||
fprintf(stderr, "%s no match\n", __FUNCTION__); /* debug */
|
||||
}
|
||||
}
|
||||
if ((xn = xpath_first(xt, "notification")) == NULL)
|
||||
goto ok;
|
||||
/* create netconf message */
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
add_preamble(cb); /* Make it well-formed netconf xml */
|
||||
cprintf(cb, "<notification><event>%s</event></notification>", event);
|
||||
if (clicon_xml2cbuf(cb, xn, 0, 0) < 0)
|
||||
goto done;
|
||||
add_postamble(cb);
|
||||
/* Send it to listening client on stdout */
|
||||
if (netconf_output(1, cb, "notification") < 0){
|
||||
|
|
@ -789,6 +772,7 @@ netconf_notification_cb(int s,
|
|||
}
|
||||
fflush(stdout);
|
||||
cbuf_free(cb);
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
if (xt != NULL)
|
||||
|
|
@ -802,7 +786,7 @@ netconf_notification_cb(int s,
|
|||
|
||||
<create-subscription>
|
||||
<stream>RESULT</stream> # If not present, events in the default NETCONF stream will be sent.
|
||||
<filter>XPATH-EXPR<(filter>
|
||||
<filter type="xpath" select="XPATHEXPR"/>
|
||||
<startTime/> # only for replay (NYI)
|
||||
<stopTime/> # only for replay (NYI)
|
||||
</create-subscription>
|
||||
|
|
@ -810,7 +794,7 @@ netconf_notification_cb(int s,
|
|||
* @param[in] h clicon handle
|
||||
* @param[in] xn Sub-tree (under xorig) at <rpc>...</rpc> level.
|
||||
* @param[out] xret Return XML, error or OK
|
||||
|
||||
* @see netconf_notification_cb for asynchronous stream notifications
|
||||
*/
|
||||
static int
|
||||
netconf_create_subscription(clicon_handle h,
|
||||
|
|
@ -840,7 +824,7 @@ netconf_create_subscription(clicon_handle h,
|
|||
goto done;
|
||||
if (event_reg_fd(s,
|
||||
netconf_notification_cb,
|
||||
xfilter?xml_dup(xfilter):NULL,
|
||||
NULL,
|
||||
"notification socket") < 0)
|
||||
goto done;
|
||||
ok:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue