It is often times useful for your application to be notified upon changes in the operational data that are being stored in CDB.
Given the following simple YANG model:
module server {
namespace "http://tail-f.com/ns/example/server";
prefix sv;
container server {
leaf oper-status {
type enumeration {
enum up;
enum down;
}
config false;
}
}
}
In order for subscription notifications to be generated, a “subscription lock” has to be obtained during the CDB write call as follows:
if ((subsock = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
confd_fatal("Failed to open socket\n");
if (cdb_connect(subsock, CDB_DATA_SOCKET, (struct sockaddr*)&addr,
sizeof (struct sockaddr_in)) < 0)
return CONFD_ERR;
if (cdb_start_session2(subsock, CDB_OPERATIONAL, CDB_LOCK_REQUEST | CDB_LOCK_WAIT) != CONFD_OK)
return CONFD_ERR;
cdb_set_namespace(subsock, sv__ns);
confd_value_t status_value;
CONFD_SET_ENUM_VALUE(&status_value, sv_up);
if (cdb_set_elem(subsock, &status_value, "/server/oper-status") != CONFD_OK)
return CONFD_ERR;
cdb_close(subsock);
Following is what needs to be done in order to subscribe to the CDB operational data subscription:
if ((subsock = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
confd_fatal("Failed to open socket\n");
if (cdb_connect(subsock, CDB_SUBSCRIPTION_SOCKET, (struct sockaddr*)&addr,
sizeof (struct sockaddr_in)) < 0)
confd_fatal("Failed to cdb_connect() to confd \n");
int spoint;
if ((status = cdb_oper_subscribe(subsock, sv__ns, &spoint, "/server/oper-status"))
!= CONFD_OK) {
fprintf(stderr, "Terminate: subscribe %d\n", status);
exit(0);
}
if (cdb_subscribe_done(subsock) != CONFD_OK)
confd_fatal("cdb_subscribe_done() failed");
In order to manually trigger the subscription without actually changing the state of the operational data, you can do the following:
if ((rsock = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
confd_fatal("Failed to open socket\n");
if (cdb_connect(rsock, CDB_DATA_SOCKET, (struct sockaddr*)&addr,
sizeof (struct sockaddr_in)) < 0)
return CONFD_ERR;
int sub_points[0];
if ((cdb_trigger_oper_subscriptions(rsock, sub_points, 0, 0) != CONFD_OK)) {
return CONFD_ERR;
}
cdb_close(rsock);
It is important to note that the cdb_trigger_oper_subscriptions() call is blocking and doesn’t return until all subscribers have acknowledged the notification. This means that it is not possible to issue the cdb_trigger_oper_subscriptions() call in a cdb subscriber process (without forking a process or spawning a thread) since it would cause a deadlock.