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-rpc1

  • an Action subscriber for /srtest:topcont2/list1/global-draw

  • example 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:

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=true

  • run 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=true

  • run 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=true

  • run 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.