Sysrepo Integration Usage
The following sections describe how to start and verify the Sysrepo Integration feature after installation is complete.
The normal usage flow is as follows:
install or activate the required YANG modules in Sysrepo
start netconfd-pro with Sysrepo Integration enabled
verify server startup and Sysrepo connectivity
run basic Edit, Get, RPC, and action tests to confirm integration
Preparing Sysrepo
Before netconfd-pro can interact with Sysrepo for a specific YANG module, that module must be installed or activated in the Sysrepo repository.
This step ensures that Sysrepo has the YANG schema available and that the target module can participate in configuration, operational data, RPC, or action processing.
For initial testing, it is also useful to load sample running configuration data and to enable a sample Sysrepo application that registers RPC and Action handlers and pushes example operational data.
Pre-requisites
The sysrepoctl tool is installed.
The sysrepocfg tool is installed.
The YANG module file is available on the local system.
Any imported or included dependent modules are also available.
The Sysrepo repository environment is configured correctly.
YANG Module Load
Install the target YANG module into the Sysrepo repository before starting netconfd-pro with Sysrepo Integration enabled.
Example:
sudo sysrepoctl -i /path/to/srtest.yang -s /path/to/search/dir -v3
The Sysrepo repository can be inspected at any time with:
sysrepoctl -l
If the module is installed successfully, it will appear in the module list together with its revision, flags, owner, permissions, submodules, and enabled features.
If a custom Sysrepo repository path or shared memory prefix is used, make sure the same environment is used for all Sysrepo tools and for netconfd-pro itself.
Configuration Load
After the YANG module is installed, sample configuration data can be loaded into the running datastore.
Example:
sudo sysrepocfg --import=./sample-running.xml -d running -m srtest -f xml -v3
Example sample-running.xml content:
<topcont xmlns="http://test.com/ns/yang/srtest">
<someleaf>42</someleaf>
<incont>
<list1>
<idx>13</idx>
<col1>hello</col1>
</list1>
</incont>
</topcont>
<topcont2 xmlns="http://test.com/ns/yang/srtest">
<list1>
<idx>11</idx>
<col1>str1</col1>
</list1>
</topcont2>
The running datastore contents can then be inspected with:
sysrepocfg -X -d running -m srtest -f xml
This command is useful to confirm that the expected configuration data is present before testing Edit, Get, RPC, or Action requests through netconfd-pro. You may need to run this command with 'sudo' depending on your sysrepo setup settings.
Sysrepo Test Application for RPC, Action, and Operational Data Examples
A sample sysrepo_app.c application can be used to provide simple
sysrepo-side handlers for initial integration testing.
#include <sysrepo.h>
#include <libyang/libyang.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static volatile int keep_running = 1;
static sr_subscription_ctx_t *g_sub = NULL;
static void on_sig(int sig) { (void)sig; keep_running = 0; }
#if defined(LYD_PRINT_WITHSIBLINGS)
#define AGT_LY_PRINT_SIBS LYD_PRINT_WITHSIBLINGS
#elif defined(LYD_PRINT_SIBLINGS)
#define AGT_LY_PRINT_SIBS LYD_PRINT_SIBLINGS
#else
#define AGT_LY_PRINT_SIBS 0
#endif
static int
rpc_cb(sr_session_ctx_t *session,
uint32_t sub_id,
const char *op_path,
const struct lyd_node *input,
sr_event_t event,
uint32_t request_id,
struct lyd_node *output,
void *private_data)
{
(void)session; (void)sub_id; (void)request_id; (void)private_data;
if (event != SR_EV_RPC) {
return SR_ERR_OK;
}
fprintf(stderr, "RPC callback: op_path=%s\n", op_path ? op_path : "<null>");
if (input) {
char *xml = NULL;
if (!lyd_print_mem(&xml, input, LYD_XML, LYD_PRINT_SHRINK | AGT_LY_PRINT_SIBS) && xml) {
fprintf(stderr, "RPC input:\n%s\n", xml);
free(xml);
}
}
{
uint32_t ly_opts = 0;
char count_buf[32];
snprintf(count_buf, sizeof(count_buf), "%u", 123);
ly_opts |= LYD_NEW_PATH_OUTPUT;
#ifdef LYD_NEW_PATH_UPDATE
ly_opts |= LYD_NEW_PATH_UPDATE;
#endif
if (lyd_new_path(output, NULL, "result-message", "OK from test-rpc1", ly_opts, NULL) != LY_SUCCESS) {
return SR_ERR_CALLBACK_FAILED;
}
if (lyd_new_path(output, NULL, "result-count", count_buf, ly_opts, NULL) != LY_SUCCESS) {
return SR_ERR_CALLBACK_FAILED;
}
}
return SR_ERR_OK;
}
static int
action_cb(sr_session_ctx_t *session,
uint32_t sub_id,
const char *op_path,
const struct lyd_node *input,
sr_event_t event,
uint32_t request_id,
struct lyd_node *output,
void *private_data)
{
(void)session; (void)sub_id; (void)request_id; (void)private_data;
if (event != SR_EV_RPC) {
return SR_ERR_OK;
}
fprintf(stderr, "ACTION callback: op_path=%s\n", op_path ? op_path : "<null>");
if (input) {
char *xml = NULL;
if (!lyd_print_mem(&xml, input, LYD_XML, LYD_PRINT_SHRINK | AGT_LY_PRINT_SIBS) && xml) {
fprintf(stderr, "ACTION input:\n%s\n", xml);
free(xml);
}
}
{
uint32_t ly_opts = 0;
char count_buf[32];
snprintf(count_buf, sizeof(count_buf), "%u", 456);
ly_opts |= LYD_NEW_PATH_OUTPUT;
#ifdef LYD_NEW_PATH_UPDATE
ly_opts |= LYD_NEW_PATH_UPDATE;
#endif
if (lyd_new_path(output, NULL, "result-message", "OK from global-draw", ly_opts, NULL) != LY_SUCCESS) {
return SR_ERR_CALLBACK_FAILED;
}
if (lyd_new_path(output, NULL, "result-count", count_buf, ly_opts, NULL) != LY_SUCCESS) {
return SR_ERR_CALLBACK_FAILED;
}
}
return SR_ERR_OK;
}
int main(void)
{
sr_conn_ctx_t *conn = NULL;
sr_session_ctx_t *sess = NULL;
int rc;
signal(SIGINT, on_sig);
signal(SIGTERM, on_sig);
rc = sr_connect(0, &conn);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_connect failed: %s\n", sr_strerror(rc));
return 1;
}
rc = sr_session_start(conn, SR_DS_RUNNING, &sess);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_session_start failed: %s\n", sr_strerror(rc));
sr_disconnect(conn);
return 1;
}
rc = sr_rpc_subscribe_tree(sess,
"/srtest:test-rpc1",
rpc_cb,
NULL,
0,
0,
&g_sub);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_rpc_subscribe_tree RPC failed: %s\n", sr_strerror(rc));
sr_session_stop(sess);
sr_disconnect(conn);
return 1;
}
rc = sr_rpc_subscribe_tree(sess,
"/srtest:topcont2/list1/global-draw",
action_cb,
NULL,
0,
SR_SUBSCR_CTX_REUSE,
&g_sub);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_rpc_subscribe_tree action failed: %s\n", sr_strerror(rc));
sr_unsubscribe(g_sub);
sr_session_stop(sess);
sr_disconnect(conn);
return 1;
}
fprintf(stderr, "RPC/action subscribers registered.\n");
sr_session_ctx_t *sess_oper = NULL;
rc = sr_session_start(conn, SR_DS_OPERATIONAL, &sess_oper);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_session_start: %s\n", sr_strerror(rc)); return 1;
}
rc = sr_set_item_str(sess_oper,
"/srtest:topcont-state/someleaf-state",
"101",
NULL,
0);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_set_item_str: %s\n", sr_strerror(rc)); return 1;
}
rc = sr_set_item_str(sess_oper,
"/srtest:topcont-state/incont-state/someleaf2",
"202",
NULL,
0);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_set_item_str: %s\n", sr_strerror(rc)); return 1;
}
rc = sr_set_item_str(sess_oper,
"/srtest:topcont-state/incont-state/list1[idx='13']/col1",
"from-push-helper", NULL, 0);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_set_item_str: %s\n", sr_strerror(rc)); return 1;
}
rc = sr_apply_changes(sess_oper, 0);
if (rc != SR_ERR_OK) {
fprintf(stderr, "sr_apply_changes: %s\n", sr_strerror(rc)); return 1;
}
printf("Operational data pushed. Keeping session alive...\n");
while (keep_running) {
sleep(1);
}
if (g_sub) {
sr_unsubscribe(g_sub);
}
sr_session_stop(sess);
sr_session_stop(sess_oper);
sr_disconnect(conn);
return 0;
}
The example code registers:
an RPC subscriber for
/srtest:test-rpc1an Action subscriber for
/srtest:topcont2/list1/global-drawexample operational data values in the operational datastore
The provided example code uses sr_rpc_subscribe_tree for the RPC and
Action handlers, then opens an operational datastore session and pushes
several example state nodes.
A typical build command is:
gcc -std=gnu99 -Wall -Wextra -g ./sysrepo_app.c \
-o /tmp/sysrepo_app \
$(pkg-config --cflags sysrepo) \
$(pkg-config --libs sysrepo) \
-lyang
A typical startup command is:
sudo /tmp/sysrepo_app
If the application starts successfully, it should register the RPC and Action subscribers and then keep the operational datastore session alive while the process is running. The example application prints a startup message indicating that the RPC and Action subscribers were registered and that operational data was pushed.
This test application is useful for validating the following flows:
RPC dispatch from netconfd-pro into Sysrepo
Action dispatch from netconfd-pro into Sysrepo
Operational data retrieval through netconfd-pro for data that was pushed into the Sysrepo operational datastore
Setup Verification
After the YANG module is loaded, the sample configuration is imported, and the optional test application is running, the Sysrepo setup can be verified with the following commands:
List installed modules:
sysrepoctl -l
Check the Sysrepo connection count:
sudo sysrepoctl -C
Dump the running datastore contents:
sudo sysrepocfg -X -d running -m srtest -f xml
The output should look as follow:
<topcont xmlns="http://test.com/ns/yang/srtest">
<someleaf>42</someleaf>
<incont>
<list1>
<idx>13</idx>
<col1>hello</col1>
</list1>
</incont>
</topcont>
<topcont2 xmlns="http://test.com/ns/yang/srtest">
<list1>
<idx>11</idx>
<col1>str1</col1>
</list1>
</topcont2>
If the sample test application is used, its console output should also show that the RPC and Action subscribers were registered successfully and that the operational data session remains active. The operational datastore contents can be inspected with:
sysrepocfg -X -d operational -m srtest -f xml -v3
The output should look as follow:
<topcont-state xmlns="http://test.com/ns/yang/srtest">
<someleaf-state>101</someleaf-state>
<incont-state>
<someleaf2>202</someleaf2>
<list1>
<idx>13</idx>
<col1>from-push-helper</col1>
</list1>
</incont-state>
</topcont-state>
At this point, the Sysrepo environment is ready for netconfd-pro startup and for basic Edit, Get, RPC, and Action testing.
Starting netconfd-pro With Sysrepo Integration
Run the server with the --with-sysrepo parameter set to true.
Note
Make sure the YANG module(s) loaded to the Sysrepo are also visible to the netconfd-pro server by using --modpath parameter.
A deployment may also include additional normal startup parameters.
Example:
netconfd-pro --with-sysrepo=true \
--modpath=/path/to/search/dir \
--module=srtest \
--log-level=debug4 \
--access-control=off
During server startup, the netconfd-pro log should indicate that the Sysrepo configuration, that was loaded in Configuration Load step, was loaded successfully.
The netconfd-pro server log should look as follows:
***** start commit phase on running for session 0, transaction 900581 *****
Start full commit of transaction 900581: 2 edits on running config
edit-transaction 900581: on session 0 by superuser@localhost
time: 2026-04-06T21:46:24Z
message-id: --
trace-id: --
datastore: running
operation: create
target: /srtest:topcont
comment: none
edit-transaction 900581: on session 0 by superuser@localhost
time: 2026-04-06T21:46:24Z
message-id: --
trace-id: --
datastore: running
operation: create
target: /srtest:topcont2
comment: none
Complete commit OK of transaction 900581 on running database
YP-HA: Active: skip update: not enabled
Generating <netconf-config-change> notification
Clearing current txid for running config
ses: free scb: superuser@none sid: 0 fd: 0
agt_cb: Adding Global EDIT3 callback
agt_cb: Adding Global GET2 callback
agt_cb: Adding Global validate RPC callback
agt_cb: Adding Global invoke RPC callback
agt_cb: Adding Global validate Action callback
agt_cb: Adding Global invoke Action callback
Filling candidate config from running config
Filling operational config from running config
agt_callhome: skip init2; --with-callhome=false
ncx: Adding Mod load callback to slot 2
ncx: Adding Mod unload callback to slot 1
netconfd-pro init OK, ready for sessions
Binding to AF_LOCAL socket /var/run/netconfd-pro/ncxserver.sock
CX thread: Listening for NCX connect requests on socket 11
Running Basic Integration Tests
After server startup and Sysrepo connectivity have been verified, basic requests can be used to confirm correct Sysrepo Integration behavior.
The recommended initial test order is:
EDIT request
GET request
RPC request
ACTION request
This sequence verifies configuration updates, configuration retrieval, RPC dispatch, Action dispatch, and operational data access through the Sysrepo Integration path.
The following example module is used in this setup:
module srtest {
yang-version 1.1;
namespace "http://test.com/ns/yang/srtest";
prefix srtest;
revision 2026-03-18 {
description
"Sysrepo test module";
}
container topcont {
leaf someleaf { type int32; }
container incont {
leaf someleaf2 { type int32; }
list list1 {
key "idx";
leaf idx { type int32; }
leaf col1 { type string; }
}
}
}
container topcont-state {
config false;
leaf someleaf-state { type int32; }
container incont-state {
leaf someleaf2 { type int32; }
list list1 {
key "idx";
leaf idx { type int32; }
leaf col1 { type string; }
}
}
}
container topcont2 {
list list1 {
key "idx";
leaf idx { type int32; }
leaf col1 { type string; }
action global-draw {
description "Draw this object";
input {
container cont1 {
leaf contleaf { type string; }
list list1 {
key idx;
leaf idx { type int32; }
leaf col1 { type string; }
}
}
leaf i { type string; }
leaf j { type uint32; }
}
output {
leaf result-message { type string; }
leaf result-count { type uint32; }
}
}
}
}
container topcont3 {
leaf someleaf3 { type int32; }
container incont {
leaf someleaf2 { type int32; }
list list1 {
key "idx";
leaf idx { type int32; }
leaf col1 { type string; }
}
}
}
rpc test-rpc1 {
input {
container cont1 {
leaf contleaf { type string; }
list list1 {
key idx;
leaf idx { type int32; }
leaf col1 { type string; }
}
}
leaf param1 { type string; }
leaf param2 { type string; }
leaf param3 { type uint32; }
}
output {
leaf result-message { type string; }
leaf result-count { type uint32; }
}
}
rpc someother-rpc {
input {
leaf param1 { type string; }
leaf param2 { type string; }
leaf param3 { type uint32; }
}
output {
leaf result-message { type string; }
leaf result-count { type uint32; }
}
}
}
Note
The test examples in the following sections assume that the
test sysrepo_app application described in
Sysrepo Test Application for RPC, Action, and Operational Data Examples
has been built and started, and is running on the same system as
netconfd-pro.
Running EDIT Request
An EDIT request is used to verify that configuration changes received by netconfd-pro are accepted and propagated correctly for modules managed through Sysrepo.
A configuration edit can be sent using any supported management interface. Typical options include:
NETCONF <edit-config>
Using DB-API Subsystem test flows, if used by the deployment
In this example, a simple NETCONF <edit-config> operation is used.
The XML request is shown below:
<edit-config>
<target>
<candidate/>
</target>
<config>
<topcont2 xmlns="http://test.com/ns/yang/srtest">
<list1>
<idx>42</idx>
<col1>str2</col1>
</list1>
</topcont2>
<topcont3 xmlns="http://test.com/ns/yang/srtest">
<someleaf3>23</someleaf3>
<incont>
<someleaf2>42</someleaf2>
<list1>
<idx>88</idx>
<col1>someleafval</col1>
</list1>
</incont>
</topcont3>
</config>
</edit-config>
The expected result is successful completion of the edit operation, without error output from either netconfd-pro or the Sysrepo.
The netconfd-pro server log may look similar to the following during the validation phase:
***** start validate phase on candidate for session 3, transaction 94 *****
undo for create op on srtest:list1
silcall for srtest:list1 [Level:2] [Prio:255] [op:create] (val: srtest:list1 [Prio:0])
undo for create op on srtest:topcont3
silcall for srtest:topcont3 [Level:1] [Prio:255] [op:create] (val: srtest:topcont3 [Prio:0])
silcall for srtest:incont [Level:2] [Prio:255] [op:create] (val: srtest:incont [Prio:0])
silcall for srtest:list1 [Level:3] [Prio:255] [op:create] (val: srtest:list1 [Prio:0])
Finished setup of transaction callbacks
Starting setup of auto-delete callbacks
Finished setup of auto-delete callbacks
Start invoking validate SIL callback for create on srtest:list1
(list1) Enter GLOBAL EDIT-3 sysrepo callback
------PHASE:validate;EDITOP: create
------Instance ID: /srtest:topcont2/srtest:list1[srtest:idx="42"]
Finished invoking user callback on srtest:list1
Start invoking validate SIL callback for create on srtest:topcont3
(topcont3) Enter GLOBAL EDIT-3 sysrepo callback
------PHASE:validate;EDITOP: create
------Instance ID: /srtest:topcont3
Finished invoking user callback on srtest:topcont3
Start invoking validate SIL callback for create on srtest:incont
(incont) Enter GLOBAL EDIT-3 sysrepo callback
------PHASE:validate;EDITOP: create
------Instance ID: /srtest:topcont3/srtest:incont
Finished invoking user callback on srtest:incont
Start invoking validate SIL callback for create on srtest:list1
(list1) Enter GLOBAL EDIT-3 sysrepo callback
------PHASE:validate;EDITOP: create
------Instance ID: /srtest:topcont3/srtest:incont/srtest:list1[srtest:idx="88"]
Finished invoking user callback on srtest:list1
Because this example uses the candidate datastore, the changes do not take effect until a separate <commit> operation is performed. After the commit completes successfully, the new configuration data is written to Sysrepo and also stored in the local netconfd-pro internal database.
The server log may then look similar to the following during the commit phase:
***** start commit phase on running for session 4, transaction 900585 *****
Start full commit of transaction 900585: 2 edits on running config
Start invoking commit SIL callback for create on srtest:list1
(list1) Enter GLOBAL EDIT-3 sysrepo callback
------PHASE:commit;EDITOP: create
------Instance ID: /srtest:topcont2/srtest:list1[srtest:idx="42"]
agt_sysrepo: Applying changes[INF] There are no subscribers for changes of the module "srtest" in running DS.
Finished invoking user callback on srtest:list1
Start invoking commit SIL callback for create on srtest:topcont3
(topcont3) Enter GLOBAL EDIT-3 sysrepo callback
------PHASE:commit;EDITOP: create
------Instance ID: /srtest:topcont3
agt_sysrepo: Applying changes
Finished invoking user callback on srtest:topcont3
Start invoking commit SIL callback for create on srtest:incont
(incont) Enter GLOBAL EDIT-3 sysrepo callback
------PHASE:commit;EDITOP: create
------Instance ID: /srtest:topcont3/srtest:incont
agt_sysrepo: Applying changes
Finished invoking user callback on srtest:incont
Start invoking commit SIL callback for create on srtest:list1
(list1) Enter GLOBAL EDIT-3 sysrepo callback
------PHASE:commit;EDITOP: create
------Instance ID: /srtest:topcont3/srtest:incont/srtest:list1[srtest:idx="88"]
agt_sysrepo: Applying changes
Finished invoking user callback on srtest:list1
SIL-SA Commit Complete callbacks OK
edit-transaction 900585: on session 4 by @::1
time: 2026-04-07T22:33:03Z
message-id: --
trace-id: --
datastore: running
operation: create
target: /srtest:topcont2/srtest:list1[srtest:idx="42"]
comment: none
edit-transaction 900585: on session 4 by @::1
time: 2026-04-07T22:33:03Z
message-id: --
trace-id: --
datastore: running
operation: create
target: /srtest:topcont3
comment: none
After the operations complete successfully, verify that the data was written to the Sysrepo datastore.
This can be done by sending the following <get-config> request:
<get-config>
<source>
<running/>
</source>
</get-config>
It can also be done directly with the Sysrepo tools:
sudo sysrepocfg -X -d running -m srtest -f xml
The exported running datastore should include the newly created nodes, for example:
<topcont xmlns="http://test.com/ns/yang/srtest">
<someleaf>42</someleaf>
<incont>
<list1>
<idx>13</idx>
<col1>hello</col1>
</list1>
</incont>
</topcont>
<topcont2 xmlns="http://test.com/ns/yang/srtest">
<list1>
<idx>11</idx>
<col1>str1</col1>
</list1>
<list1>
<idx>42</idx>
<col1>str2</col1>
</list1>
</topcont2>
<topcont3 xmlns="http://test.com/ns/yang/srtest">
<someleaf3>23</someleaf3>
<incont>
<someleaf2>42</someleaf2>
<list1>
<idx>88</idx>
<col1>someleafval</col1>
</list1>
</incont>
</topcont3>
Running GET Request for Operational Data
A GET request can be used to verify that operational data is retrieved correctly through netconfd-pro when Sysrepo Integration is enabled.
An example showing retrieval of configuration data is already provided in the Running EDIT Request section. The focus here is on operational data.
In this example, netconfd-pro retrieves operational data from Sysrepo.
The example sysrepo_app application described in
Sysrepo Test Application for RPC, Action, and Operational Data Examples
is used to populate sample operational data in the Sysrepo operational
datastore.
To verify this path, send a normal GET request to netconfd-pro for the operational data node.
In this example, a RESTCONF GET request is used:
curl -X GET \
-H "Accept: application/yang-data+json" \
http://localhost/restconf/data/srtest:topcont-state
The response may look similar to the following:
{
"srtest:topcont-state": {
"someleaf-state":101,
"incont-state": {
"someleaf2":202,
"list1": [
{
"idx":13,
"col1":"from-push-helper"
}
]
}
}
}
The netconfd-pro server log may include messages similar to the following during request processing:
agt_restcmn: GET /restconf/data/topcont-state for 4=@::1
agt_restcmn: Got method GET on request_uri '/restconf/data/topcont-state'
agt_restcmn: Got request_target_obj 'srtest:topcont-state'
agt_restcmn: Got request_launch value 'ietf-restconf:data'
agt_restcmn: Got request_terminal value 'ietf-restconf:data'
agt_restcmn: 'Accept' header set to 'application/json'
getcb: starting sysrepo retrieval for 'srtest:topcont-state'
getcb: process_get2_child_obj for 'topcont-state' in All in One API mode
getcb: start GET_VALUE for 'topcont-state'
Enter GLOBAL GET2 sysrepo callback for 'srtest:topcont-state'
object: 'srtest:topcont-state'
path: /srtest:topcont-state
mode: GET
agt_sysrepo: sysrepo path: /srtest:topcont-state
getcb: end GET_VALUE for 'topcont-state', status (ok)
getcb: begin AIO buffer parsing
getcb: AIO GET2 buffer:
<topcont-state xmlns="http://test.com/ns/yang/srtest"><someleaf-state>101</someleaf-state><incont-state><someleaf2>202</someleaf2><list1><idx>13</idx><col1>from-push-helper</col1></list1></incont-state></topcont-state>
This example shows that netconfd-pro uses its internal Sysrepo Integration GET2 handling to retrieve operational data from sysrepo.
No module-specific SIL code is required on the netconfd-pro side for this retrieval path. The required setup is:
install the YANG module in sysrepo
load the same YANG module in netconfd-pro
start netconfd-pro with
--with-sysrepo=truerun the sysrepo-side application or plugin that provides the operational data
Once this setup is complete, netconfd-pro can retrieve the operational data automatically through the Sysrepo Integration path.
Running RPC Request
An RPC request can be used to verify that RPC operations are dispatched correctly through netconfd-pro when Sysrepo Integration is enabled.
In this example, netconfd-pro forwards the RPC request to Sysrepo. The
example sysrepo_app application described in
Sysrepo Test Application for RPC, Action, and Operational Data Examples
is used to register an RPC subscriber for the /srtest:test-rpc1
operation and to return sample output values.
The example application returns result-message set to OK from test-rpc1 and result-count set to 123.
To verify this path, send a normal RPC request to netconfd-pro for the test-rpc1 operation.
In this example, a NETCONF RPC request is used:
<rpc message-id="4"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<test-rpc1 xmlns="http://test.com/ns/yang/srtest">
<param1>test</param1>
</test-rpc1>
</rpc>
The response may look similar to the following:
<rpc-reply message-id="4"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<result-message xmlns="http://test.com/ns/yang/srtest">OK from test-rpc1</result-message>
<result-count>123</result-count>
</rpc-reply>
The netconfd-pro server log may include messages similar to the following during request processing:
Enter GLOBAL RPC VALIDATE sysrepo callback
modname=srtest
RPC Qualified Name=test-rpc1
RPC Name=test-rpc1
agt_sysrepo: Found active sysrepo subscriber(s) for RPC 'test-rpc1'
Enter GLOBAL RPC INVOKE sysrepo callback
modname=srtest
RPC Qualified Name=test-rpc1
RPC Name=test-rpc1
[INF] Published event "rpc" "/srtest:test-rpc1" with ID 2 priority 0 for 1 subscribers.
[INF] Event "rpc" with ID 2 priority 0 succeeded.
agt_sysrepo: Got Sysrepo XML Output:
<test-rpc1 xmlns="http://test.com/ns/yang/srtest">
<result-message>OK from test-rpc1</result-message>
<result-count>123</result-count>
</test-rpc1>
This example shows that netconfd-pro uses its internal Sysrepo Integration RPC handling to validate the RPC, detect active Sysrepo subscribers, invoke the Sysrepo callback, and return the result to the client.
No module-specific SIL code is required on the netconfd-pro side for this RPC path. The required setup is:
install the YANG module in sysrepo
load the same YANG module in netconfd-pro
start netconfd-pro with
--with-sysrepo=truerun the sysrepo-side application or plugin that provides the RPC subscriber for the requested operation
Once this setup is complete, netconfd-pro can dispatch the RPC automatically through the Sysrepo Integration path.
Running ACTION Request
An Action request can be used to verify that YANG Actions are dispatched correctly through netconfd-pro when Sysrepo Integration is enabled.
Unlike a top-level RPC, an action is attached to a specific datastore node instance. For this reason, the parent node for the action must already exist in the datastore before the action request is sent. In this example, the Running EDIT Request step is required first so that the target /srtest:topcont2/list1[idx='11'] instance exists.
In this example, netconfd-pro forwards the Action request to sysrepo.
The example sysrepo_app application described in
Sysrepo Test Application for RPC, Action, and Operational Data Examples
registers an action subscriber for
/srtest:topcont2/list1/global-draw and returns the sample output
values result-message = OK from global-draw and
result-count = 456.
To verify this setup, send a RESTCONF POST request to the Action target. The request body contains the Action input parameters.
Example request:
curl -X POST \
-H "Accept: application/yang-data+json" \
-H "Content-Type: application/yang-data+xml" \
--data-binary @input.xml \
http://localhost/restconf/data/srtest:topcont2/list1=11/global-draw
Example input.xml content:
<input xmlns="http://test.com/ns/yang/srtest">
<cont1>
<contleaf>someleaf</contleaf>
<list1>
<idx>11</idx>
<col1>listleaf</col1>
</list1>
</cont1>
<i>par1</i>
<j>13</j>
</input>
The netconfd-pro server log may include messages similar to the following during request processing:
Enter GLOBAL ACTION VALIDATE sysrepo callback
modname=srtest
Action Qualified Name=global-draw
Action Name=global-draw
agt_sysrepo: Found active sysrepo subscriber(s) for Action 'global-draw'
Enter GLOBAL ACTION INVOKE sysrepo callback
modname=srtest
Action Qualified Name=global-draw
Action Name=global-draw[INF] No datastore changes to apply.
[INF] Published event "rpc" "/srtest:topcont2/list1/global-draw" with ID 3 priority 0 for 1 subscribers.
[INF] Event "rpc" with ID 3 priority 0 succeeded.
agt_sysrepo: Got Sysrepo XML Output:
<global-draw xmlns="http://test.com/ns/yang/srtest">
<result-message>OK from global-draw</result-message>
<result-count>456</result-count>
</global-draw>
This example shows that netconfd-pro uses its internal Sysrepo Integration Action handling to validate the Action, detect active Sysrepo subscribers, invoke the Sysrepo callback, and return the result to the client.
No module-specific SIL code is required on the netconfd-pro side for this Action path. The required setup is:
install the YANG module in sysrepo
load the same YANG module in netconfd-pro
ensure that the target parent instance already exists in the datastore
start netconfd-pro with
--with-sysrepo=truerun the sysrepo-side application or plugin that provides the Action subscriber for the requested operation
Once this setup is complete, netconfd-pro can dispatch the Action automatically through the Sysrepo Integration path.