Devel log says " devel-c Daemon debug registered for non-existing actionpoint 'debug-rpc'"

Hi,

I am attempting to implement an RPC in a supplied yang file. Whenever I try to register for the rpc, I am getting the “registered for non-existing actionpoint” error. I’ve tried to distill the issue down to this:
Yang file:

module debug {

 yang-version 1.1;


 namespace "urn:debug";
 prefix "debug";


import ietf-yang-types {
prefix yang;
 }

import tailf-common { prefix tailf; }

 description "Sample to explore two element string key when second key is empty string";
 revision 2019-10-22 {
  description "0.0.1";
 }


   rpc debug-rpc {
    input {
         leaf input_val {
        type uint32;
      }
    }
    output {
      leaf output_val {
       type uint32;
      }
    }
  }

}

Code that registers the callback:

bool register_callbacks(confd_daemon_ctx* dctx)
{
    std::cout << "Registering callback for " << confd_hash2str(debug_debug_rpc) << std::endl;
    confd_action_cbs acb;
    ::memset(&acb, 0, sizeof(acb));
    strcpy(acb.actionpoint, confd_hash2str(debug_debug_rpc));
    acb.init = init_cb;
    acb.action = action_cb;
    acb.abort = 0;

    auto reg_result = confd_register_action_cbs(dctx, &acb);
    if (CONFD_OK == reg_result) {

        reg_result = confd_register_done(dctx);

        if (CONFD_OK != reg_result) {
            std::cout << "Failed to complete registration result" << std::endl;
        }
    } else {
        std::cout << "Failed to register callback" << std::endl;
    }

    return reg_result;

}

Error msg in devel.log
31-Oct-2019::09:17:08.047 localhost confd[15903]: devel-c Daemon debug registered for non-existing actionpoint ‘debug-rpc’

Any obvious mistakes here?

When I use the tailf annotations for an action point I don’t seem to have this problem.

Thanks in advance for any suggestions.

Dave

So, you are setting a struct element called actionpoint to the name of the RPC - no warning bells ringing?:slight_smile:

You need to do the exact same thing for an RPC as for an action (or tailf:action) - add or annotate a tailf:actionpoint and use that in your callback registration. It’s reasonable at least from an implementation point of view to think of an RPC as “just a special type of action”.

Thank you for the response.

I probably did not describe the issue, which could just be my own misunderstanding, very well in the post title. After writing a more simplified example, my question becomes “Is it possible to register for a rpc with out adding the tailf:actionpoint annotation to my model?”

If there is a different function to call to register a callback for an rpc rather than for an actionpoint, that could be the issue that I don’t know that.

Relevant changes to model:

  rpc debug-rpc1 {
    input {
      leaf input_val {
        type uint32;
      }
    }
    output {
      leaf output_val {
       type uint32;
      }
    }
  }

  rpc debug-rpc2 {
    tailf:actionpoint debug-rpc2-ap;
     input {
      leaf input_val {
        type uint32;
      }
    }
    output {
      leaf output_val {
       type uint32;
      }
    }
  }
}

Registration code:

std::cout &lt;&lt; "Registering callback for " &lt;&lt; confd_hash2str(debug_debug_rpc1) &lt;&lt; std::endl;
confd_action_cbs acb;
::memset(&amp;acb, 0, sizeof(acb));
strcpy(acb.actionpoint, confd_hash2str(debug_debug_rpc1));
acb.init = init_cb;
acb.action = action_cb;
acb.abort = 0;
auto reg_result = confd_register_action_cbs(dctx, &amp;acb);

confd_action_cbs acb2;
::memset(&amp;acb2, 0, sizeof(acb2));
std::cout &lt;&lt; "Registering callback for " &lt;&lt; debug__actionpointid_debug_rpc2_ap &lt;&lt; std::endl;
strcpy(acb2.actionpoint, debug__actionpointid_debug_rpc2_ap);
acb2.init = init_cb;
acb2.action = action_cb;
acb2.abort = 0;

Output of invoking the RPCs:

cat cmd-invoke-rpc1.xml
<?xml version="1.0" encoding="UTF-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <capabilities>
    <capability>urn:ietf:params:netconf:base:1.0</capability>
  </capabilities>
</hello>
]]>]]>
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"  message-id="1">
    <debug-rpc1 xmlns="urn:debug">
        <input_val> 42 </input_val>
    </debug-rpc1>
</rpc>
]]>]]>
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
  <close-session/>
</rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <rpc-error>
    <error-type>application</error-type>
    <error-tag>operation-failed</error-tag>
    <error-severity>error</error-severity>
    <error-path xmlns:debug="urn:debug" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
    /nc:rpc/debug:debug-rpc1
  </error-path>
    <error-message xml:lang="en">not yet implemented</error-message>
    <error-info>
      <bad-element>debug-rpc1</bad-element>
    </error-info>
  </rpc-error>
</rpc-reply>

cat cmd-invoke-rpc2.xml
<?xml version="1.0" encoding="UTF-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <capabilities>
    <capability>urn:ietf:params:netconf:base:1.0</capability>
  </capabilities>
</hello>
]]>]]>
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"  message-id="1">
    <debug-rpc2 xmlns="urn:debug">
        <input_val> 42 </input_val>
    </debug-rpc1>
</rpc>
]]>]]>
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
  <close-session/>
</rpc>
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <output_val xmlns="urn:debug">42</output_val>
</rpc-reply>

Perhaps most simply:

In order to provide an rpc, must you change a yang model (often supplied by a 3rd party org like the ietf) to add the tailf:actionpoint annotation?

Well, in the previous post I wrote:

I.e. I think it should be pretty clear that the answer to your new question is “no”.:slight_smile:

There isn’t.

This is ConfD’s “netconf-client-friendly” way of saying “the developer hasn’t added an actionpoint for this RPC yet”.

What is your actual problem, i.e. why don’t you want to add a tailf:actionpoint even though you have verified that this is what works? I assume you are aware that you don’t need to modify the actual YANG module for this, but can use an annotation module with tailf:annotate? Ah, while I was writing this, your next message arrived:

And the answer to that is thus "No, you can use tailf:annotate in an annotation module that you include in the compilation via the -a / --annotate option to confdc. There are some illustrations of this in the $CONFD_DIR/src/confd/yang directory in the release (check the Makefile there), as well as in some of the examples (look for files matching *-ann.yang - that’s just a convention, but pretty handy).

Thank you. That fills in (the current part of) my knowledge gap.
I will examine the examples.

Thanks again,

Dave

P.S. for future forum searches, as of confd-basic-7.1.1:

~ confd-basic-7.1.1  find . -name *-ann.yang
./src/confd/yang/ietf-yang-patch-ann.yang
./src/confd/yang/ietf-restconf-ann.yang
./src/confd/yang/tailf-common-monitoring-ann.yang
./src/confd/yang/ietf-restconf-monitoring-ann.yang
./src/confd/yang/ietf-netconf-acm-ann.yang
./src/confd/yang/ietf-yang-library-ann.yang
./src/confd/yang/ietf-yang-schema-mount-ann.yang
./src/confd/yang/ietf-netconf-notifications-ann.yang
./src/confd/yang/ietf-netconf-monitoring-ann.yang
./src/confd/yang/tailf-confd-monitoring-ann.yang
./src/confd/confd_aaa_bridge/bridge-ann.yang
./examples.confd/linuxcfg/ietf_routing/ietf-routing-ann.yang
./examples.confd/linuxcfg/ietf_routing/ietf-ipv4-unicast-routing-ann.yang
./examples.confd/linuxcfg/ietf_routing/ietf-ipv6-unicast-routing-ann.yang
./examples.confd/linuxcfg/ietf_system/ietf-system-ann.yang
./examples.confd/linuxcfg/ietf_interfaces/ietf-interfaces-ann.yang
./examples.confd/linuxcfg/ietf_ip/ietf-ip-ann.yang