Giter Site home page Giter Site logo

sysrepo-cpp's Introduction

C++ bindings for sysrepo

License Gerrit Zuul CI

sysrepo-cpp are object-oriented bindings of the sysrepo library. It uses RAII for automatic memory management.

Dependencies

  • sysrepo - the devel branch (even for the master branch of sysrepo-cpp)
  • libyang-cpp - C++ bindings for libyang
  • C++20 compiler (e.g., GCC 10.x+, clang 10+)
  • CMake 3.19+
  • optionally for built-in tests, Doctest as a C++ unit test framework
  • optionally for built-in tests, trompeloeil for mock objects in C++

Building

sysrepo-cpp uses CMake for building. The standard way of building sysrepo-cpp looks like this:

mkdir build
cd build
cmake ..
make
make install

Usage

Differences from the previous sysrepo C++ bindings

  • Most of the classes in sysrepo-cpp are not directly instantiated by the user, and are instead returned by methods. The only class directly instantiated by the user is the sysrepo::Connection class.
  • The classes are no longer wrapped by std::shared_ptr. However, they are still copyable and one can have multiple instances of, i.e., sysrepo::Session that refer to the same session. Memory management will still work automatically.

Connections and sessions

The core classes for sysrepo-cpp are sysrepo::Connection and sysrepo::Session. Creating those is straightforward.

auto session = sysrepo::Connection{}.sessionStart();

Examples of simple usage

These are some of the most typical operations supported by sysrepo-cpp.

Editing data and retrieving data

auto session = sysrepo::Connection{}.sessionStart();
session.setItem("/module:myCont/myLeaf", "some-value");
session.applyChanges();

if (auto data = session.getData("/module:myCont/myLeaf")) {
    // `data` points to "/module:myCont", to get the leaf, we need to use findPath
    auto leaf = data.findPath("/module:myCont/myLeaf");
    std::cout << leaf->asTerm().valueStr() << "\n";
} else {
    std::cout << "no data\n";
}

Note: sysrepo::Session::getData always returns the first top-level node of the data that corresponds to the XPath you provided. You might need to use the findPath method on data to get the actual node you wanted.

Creating a subscription for module changes

sysrepo::ModuleChangeCb moduleChangeCb = [] (auto session, auto, auto, auto, auto, auto) {
    for (const auto& change : session.getChanges()) {
        // do stuff
    }
    return sysrepo::ErrorCode::Ok;
};

auto session = sysrepo::Connection{}.sessionStart();
auto sub = sess.onModuleChange("my-module-name", moduleChangeCb);
sub.onRPCAction(...);

Using sysrepo-cpp in your classes

In C++, one usually wants to create a class that groups all of the sysrepo-cpp classes, mainly sessions and subscriptions. Here is an example of such class:

class SysrepoManager {
public:
    SysrepoManager()
        : m_sess(sysrepo::Connection{}.sessionStart())
        , m_sub(/*???*/) // How to initialize this?
    {
    }

private:
    sysrepo::Session m_sess;
    sysrepo::Subscription m_sub;
};

The example illustrates a small caveat of the sysrepo::Subscription class: it is not possible to have an "empty" instance of it. Every sysrepo::Subscription instance must already point to a valid subscription. There are two ways of solving this:

  • Just initialize the m_sub field in the member initializer list. This works if one wants to immediately subscribe to something on the creation of the example class.
  • If actual empty subscriptions are needed std::optional<sysrepo::Subscription> can be used as the type of m_sub. This enables having no active subscriptions, however, when actually creating subscriptions, the first call must use m_sess and any following should use the m_sub. Example:
    m_sub = m_sess.onModuleChange(...);
    m_sub.onRPCAction(...);
    m_sub.onModuleChange(...);

For more examples, check out the examples/ and the tests/ directory.

Contributing

The development is being done on Gerrit here. Instructions on how to submit patches can be found here. GitHub Pull Requests are not used.

sysrepo-cpp's People

Contributors

gotthardp avatar jktjkt avatar peckato1 avatar syyyr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sysrepo-cpp's Issues

Can Sysrepo-cpp be used with netopeer?

Hello,

I am working with netooper2 and I am wondering if sysrepo-cpp and libyang-cpp can be used with libnetconf2 and netopeer2?

I am looking to deploy netopeer2 in a c++ project and I want to ask how can I use the sysrep-cpp ?

Below is how I am starting the netconf server at the moment, can I use libyang-cpp and sysrepo-cpp instead of libyang and sysrepo?

sudo -i

mkdir NetConfServer
cd NetConfServer

#Install libyang
git clone https://github.com/CESNET/libyang.git
cd libyang
mkdir build && cd build && cmake .. && make && make install

#Install sysrepo
cd ..
git clone https://github.com/sysrepo/sysrepo.git
cd sysrepo
mkdir build && cd build && cmake .. && make && make install

# Install libnetconf2
cd ..
git clone https://github.com/CESNET/libnetconf2.git
cd libnetconf2
mkdir build && cd build && cmake .. && make && make install

# Install Netopeer2
cd ..
git clone https://github.com/CESNET/netopeer2.git
cd netopeer2
mkdir build && cd build && cmake -GENERATE_HOSTKEY=OFF -MERGE_LISTEN_CONFIG=OFF .. && make && make install

Thanks,

Tarek

Session::deleteItem for operational datastore

The sysrepo documentation says the sr_delete_item cannot be used for the operational store-- the sr_oper_delete_item_str should be used instead. The Session::deleteItem doesn't say that, which could suggest it can be used for any store, but I didn't find the sr_oper_delete_item_str in the implementation.
I believe the Session::deleteItem should either call sr_session_get_ds to check the datastore and call sr_oper_delete_item_str in case of an operational store, or there should be another method for deleting items from the operational store, right? The first option may be more user-friendly, the second just wraps whatever sysrepo offers.

compile error " sr_get_changes"

Hi!
I've got an error when start to build this:

_[vmware@srv-01 build]$ make
[ 5%] Building CXX object CMakeFiles/sysrepo-cpp.dir/src/Connection.cpp.o
[ 11%] Building CXX object CMakeFiles/sysrepo-cpp.dir/src/Enum.cpp.o
[ 16%] Building CXX object CMakeFiles/sysrepo-cpp.dir/src/Session.cpp.o
/home/vmware/sysrepo-cpp-master/src/Session.cpp: In member function ‘std::optional sysrepo::Session::getPendingChanges() const’:
/home/vmware/sysrepo-cpp-master/src/Session.cpp:217:20: error: ‘sr_get_changes’ was not declared in this scope; did you mean ‘sr_has_changes’?
217 | auto changes = sr_get_changes(m_sess.get());
| ^~~~~~~~~~~~~~
| sr_has_changes
/home/vmware/sysrepo-cpp-master/src/Session.cpp: At global scope:
/home/vmware/sysrepo-cpp-master/src/Session.cpp:573:2: warning: extra ‘;’ [-Wpedantic]
573 | };
| ^
make[2]: *** [CMakeFiles/sysrepo-cpp.dir/src/Session.cpp.o] Error 1
make[1]: *** [CMakeFiles/sysrepo-cpp.dir/all] Error 2
make: *** [all] Error 2
_

Can you please help with this issue?

Clarification: Using wrapUnmanagedSession in sr_plugin_init_cb called by sysrepo plugin deamon

I'm running sysrepo plugins which are being initialized by the sysrepo plugin daemon calling sr_plugin_init_cb(sr_session_ctx_t *running_session, void **private_data).
Here I found an issue where wrapUnmanagedSession has been exported as a public API so that it can be used to create a sysrepo object from the incoming running_session. However, this effectively takes over the ownership of running_session meaning that the underlying session will be destroyed in the object's destructor so that any other plugin, that's running in parallel, may crash afterwards since the sysrepo plugin daemon calls sr_plugin_init_cb of all plugins with the very same session.
Is my understanding correct?

GoogleTest as unit test framework

Thanks for this project, it helps a lot. However, we're having a hard time in using it in our development framework as we rely on GoogleTest for unit testing. So far it only works when we use an entirely different Session class when testing. It would be very nice if GoogleTest were supported natively. Is there a change for this to be supported in the future?

Wrap for sr_get_items and sr_get_subtree

I understand that getData is a super set of all GET, but sr_get_items and sr_get_subtree are useful(more efficient in many use cases). I wonder if you have a plan to add these?

Git tags?

Could sysrepo-cpp benefit from versioning just like sysrepo does, specifically in the form of git tags, but, less importantly, maybe also in CMakeLists.txt and in github releases?

The lack of git tags forces use of commit ids like specified here which feels risky because the commit might not point to a stable variant. Much like, for example, one would prefer to use v2.2.73 or v2.2.105 in sysrepo as opposed to any of the 149 commits in between.

If this is more of a rolling release project, and the latest commit is always the most stable, that is understandable.

Versions could still be useful for bug reporting and for posterity in general.

This would also apply to libyang-cpp.

Thank you!

Session::getData confusion

Hello. I believe in the documentation there is some confusion around Session::getData.

(If I understand it well) the sr_get_data returns a subtree, i.e. a path from the root to a given node, plus all descendants of this node. Therefore, if someone needs a specific value, one needs to call the DataNode::findPath first. This is actually quite good, because one can get a subtree and then search multiple related values in it (like latitude and longitude).

The documentation however is worded like if Session::getData returned the value:

  1. I believe the example in README works only because the value requested is the root element. If the path was longer, the findPath would need be used, right?

    sysrepo-cpp/README.md

    Lines 47 to 50 in b49fc99

    auto data = session.getData("/module:leaf");
    if (data) {
    std::cout << data->asTerm().valueStr() << "\n";
    } else {
  2. The Session::getData documentation talks about the element to be retrieved and returning requested data which may also be confusing. I believe it returns a full subtree containing that element, not the element itself (hence the need for subsequent findPath if one really needs the node data, unless it's a root element, which feels to be a quite rare case in the NETCONF world).

    sysrepo-cpp/src/Session.cpp

    Lines 157 to 166 in b49fc99

    /**
    * Retrieves a tree specified by the provided XPath.
    *
    * Wraps `sr_get_data`.
    *
    * @param path Path of the element to be retrieved.
    *
    * @returns std::nullopt if no matching data found, otherwise the requested data.
    */
    std::optional<libyang::DataNode> Session::getData(const char* path) const

(If my suspicion about getData is correct) I suggest to slightly amend the documentation so that newcomers like me better understand how to retrieve data from their trees.

Support of sr_lock()

Sysrepo's C API features the sr_lock() function, with which race conditions can be avoided when multiple clients want to modify a datastore in parallel. With the locking mechanism there's a race condition in which the first changes may be overwritten by latter ones unintentionally.
Would it be possible to implement that feature in the Session class?

`sysrepo::Subcription` is not default constructible

Currently, the only way to have a sysrepo::Subcription as a member, is to either initialize it directly in class member initializer list, or make it into an std::optional<sysrepo::Subcription>.

The first solution is kind of undesirable, because it means that there is a lot of code in the member init-list. The second one means that sometimes, you may forget that to assign the optional on the first subscription (if you're doing multiple subscriptions).

EditOptions vs sr_edit_flag_t

By wrapping sr_edit_flag_t with a Enum, seems I can not set multiple edit flags anymore, since options in Enum EditOptions are mutual-exclusive. How should deal with this?

Similarly, we would have the same issue if I wrap sr_get_oper_flag_t using a Enum?

Add SOVERSION to the shared lib

Would you please add SOVERSION to the shared library, just like sysrepo has (or somehow similarly)?

set_target_properties(sysrepo PROPERTIES VERSION ${SYSREPO_SOVERSION_FULL} SOVERSION ${SYSREPO_SOVERSION})

Yocto Linux reports a "QA issue" that there is none.

Sysrepo subscriber type enum mismatch

When compiling master on 0f6791e
I run into enum conflicts that are picked up by your static asserts:

Step 32/40 : RUN     cmake -D BUILD_TESTING=0 -D WITH_DOCS=0 ..; make; make install
 ---> Running in 84d65f9f5814
-- The CXX compiler identification is GNU 10.2.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Git: /usr/bin/git (found version "2.30.2") 
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2") 
-- Checking for modules 'libyang-cpp=alpha;libyang-cpp'
--   Found libyang-cpp, version alpha
--   Found libyang-cpp, version alpha
-- Checking for modules 'sysrepo>=2.0.37;sysrepo'
--   Found sysrepo, version 2.0.53
--   Found sysrepo, version 2.0.53
-- Configuring done
-- Generating done
-- Build files have been written to: /app/sysrepocpp/build
[ 16%] Building CXX object CMakeFiles/sysrepo-cpp.dir/src/Connection.cpp.o
In file included from /app/sysrepocpp/src/Connection.cpp:14:
/app/sysrepocpp/src/utils/enum.hpp:60:62: error: static assertion failed
   60 | static_assert(toSubscribeOptions(SubscribeOptions::NoThread) == SR_SUBSCR_NO_THREAD);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:61:61: error: static assertion failed
   61 | static_assert(toSubscribeOptions(SubscribeOptions::Passive) == SR_SUBSCR_PASSIVE);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:62:62: error: static assertion failed
   62 | static_assert(toSubscribeOptions(SubscribeOptions::DoneOnly) == SR_SUBSCR_DONE_ONLY);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:63:61: error: static assertion failed
   63 | static_assert(toSubscribeOptions(SubscribeOptions::Enabled) == SR_SUBSCR_ENABLED);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:64:60: error: static assertion failed
   64 | static_assert(toSubscribeOptions(SubscribeOptions::Update) == SR_SUBSCR_UPDATE);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:65:63: error: static assertion failed
   65 | static_assert(toSubscribeOptions(SubscribeOptions::OperMerge) == SR_SUBSCR_OPER_MERGE);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:66:67: error: static assertion failed
   66 | static_assert(toSubscribeOptions(SubscribeOptions::ThreadSuspend) == SR_SUBSCR_THREAD_SUSPEND);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/sysrepo-cpp.dir/build.make:76: CMakeFiles/sysrepo-cpp.dir/src/Connection.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/sysrepo-cpp.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
Consolidate compiler generated dependencies of target sysrepo-cpp
[ 16%] Building CXX object CMakeFiles/sysrepo-cpp.dir/src/Connection.cpp.o
In file included from /app/sysrepocpp/src/Connection.cpp:14:
/app/sysrepocpp/src/utils/enum.hpp:60:62: error: static assertion failed
   60 | static_assert(toSubscribeOptions(SubscribeOptions::NoThread) == SR_SUBSCR_NO_THREAD);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:61:61: error: static assertion failed
   61 | static_assert(toSubscribeOptions(SubscribeOptions::Passive) == SR_SUBSCR_PASSIVE);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:62:62: error: static assertion failed
   62 | static_assert(toSubscribeOptions(SubscribeOptions::DoneOnly) == SR_SUBSCR_DONE_ONLY);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:63:61: error: static assertion failed
   63 | static_assert(toSubscribeOptions(SubscribeOptions::Enabled) == SR_SUBSCR_ENABLED);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:64:60: error: static assertion failed
   64 | static_assert(toSubscribeOptions(SubscribeOptions::Update) == SR_SUBSCR_UPDATE);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:65:63: error: static assertion failed
   65 | static_assert(toSubscribeOptions(SubscribeOptions::OperMerge) == SR_SUBSCR_OPER_MERGE);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
/app/sysrepocpp/src/utils/enum.hpp:66:67: error: static assertion failed
   66 | static_assert(toSubscribeOptions(SubscribeOptions::ThreadSuspend) == SR_SUBSCR_THREAD_SUSPEND);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/sysrepo-cpp.dir/build.make:76: CMakeFiles/sysrepo-cpp.dir/src/Connection.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/sysrepo-cpp.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

Comparing this with sysrepo Version 2.0.53 in src/sysrepo_types.h (https://github.com/sysrepo/sysrepo/blob/39bc5adb98026af355febcca5abf27d44ebf6f10/src/sysrepo_types.h#L345) the former values were actually correct.

Only

 /**
     * @brief This option enables the application to re-use an already existing subscription context previously returned
     * from any sr_*_subscribe call instead of requesting the creation of a new one. In that case a single
     * ::sr_unsubscribe call unsubscribes from all subscriptions filed within the context.
     */
    SR_SUBSCR_CTX_REUSE = 1,

was missing from the list.

sysrepo::Lock destructor not respecting the datastore the lock was created for

The following code snipped leads to an error saying that a Yang module was not locked by this session:

{
  session.switchDatastore( sysrepo::Datastore::Candidate );
  sysrepo::Lock lock( session );
  session.switchDatastore( sysrepo::Datastore::Running );
}

Looks like the Lock destructor tries to call sr_unlock for the wrong datastore.
Even after session/process termination the candidate datastore remains locked in shared memory by the destroyed session.

How to check if a module is installed in sysrepo?

std::string moduleName = "examples";
I call auto data = session.getData("/" + moduleName+":*//.").c_str()); and when the module is not installed my application is crashing.

Let say I installed example.yang and I want to check in my c++ code if this module is installed and then based on that I log it.

private_data support in the subscription API

Hi,

are there any plans for adding support for user defined private_data to the subscription API, for example in the onOperGet() or onModuleChange() functions the same way it is defined in the sysrepo subscription API? We are considering switching to C++ and would like to have a user defined context stored and retrieved in operational/module change callbacks.

libyang-cpp not found

Hi!
I try to build this and I got an error:

$ cmake ..
-- Checking for modules 'libyang-cpp=1.1.0;libyang-cpp'
-- No package 'libyang-cpp' found
-- No package 'libyang-cpp' found
CMake Error at /usr/local/share/cmake-3.23/Modules/FindPkgConfig.cmake:603 (message):
A required package was not found
Call Stack (most recent call first):
/usr/local/share/cmake-3.23/Modules/FindPkgConfig.cmake:825 (_pkg_check_modules_internal)
CMakeLists.txt:30 (pkg_check_modules)
-- Configuring incomplete, errors occurred!

but just before I installed "libyang-cpp" as well:

$ sudo make install
[ 58%] Built target yang-cpp
[ 66%] Built target DoctestIntegration
[ 75%] Built target test_context
[ 83%] Built target test_data_node
[ 91%] Built target test_schema_node
[100%] Built target test_unsafe
Install the project...
-- Install configuration: ""
-- Up-to-date: /usr/local/lib64/libyang-cpp.so
-- Up-to-date: /usr/local/include/libyang-cpp
-- Up-to-date: /usr/local/include/libyang-cpp/ChildInstantiables.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/Collection.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/Context.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/DataNode.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/Enum.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/Module.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/SchemaNode.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/Set.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/Type.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/Utils.hpp
-- Up-to-date: /usr/local/include/libyang-cpp/Value.hpp
-- Up-to-date: /usr/local/lib64/pkgconfig/libyang-cpp.pc

Augmented predicates in Session::onModuleChange XPath

Hi!

I'm playing around with module_change_example.cpp prior to implementing my own plugin. Currently I have ietf-interfaces augmented by ieee802-dot1q-bridge & ieee802-dot1q-sched-bridge. I would like to filter interfaces to be those with supported-list-max>0.

In netopeer2-cli connected to netopeer2-server on the same machine, I am able to run

get-config --source running --filter-xpath "/ietf-interfaces:interfaces/interface[ieee802-dot1q-bridge:bridge-port/ieee802-dot1q-sched-bridge:gate-parameter-table/supported-list-max>0]"

Which returns all interfaces fulfilling the predicate (e.g. br0). However, if I run module_change_example.cpp as

./module_change_example ietf-interfaces "/ietf-interfaces:interfaces/interface[ieee802-dot1q-bridge:bridge-port/ieee802-dot1q-sched-bridge:gate-parameter-table/supported-list-max>0]"

And send a simple change via netopeer2-cli (gate-enabled was previously false)

edit-config --target running --config=change.xml

<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
  <interface>
    <name>br0</name>
    <bridge-port xmlns="urn:ieee:std:802.1Q:yang:ieee802-dot1q-bridge">
      <gate-parameter-table xmlns="urn:ieee:std:802.1Q:yang:ieee802-dot1q-sched-bridge">
        <gate-enabled>true</gate-enabled>
      </gate-parameter-table>
    </bridge-port>
  </interface>
</interfaces>

The changes are applied but the example plugin does not print any information. With no xpath or xpath as ietf-interfaces:interfaces/interface[name='br0'] module_change_example reacts to the changes as expected. Not sure whether this is directly related to sysrepo-cpp or the other libraries, or intended behavior in the first place but would highly appreciate some help.

Using most recent releases libyang 3.1.0, libnetconf2 3.3.3, sysrepo 2.10.1, netopeer2 2.2.28 & the following commits of sysrepo-cpp and libyang-cpp with libyang 3 support:

Support for the plugins API

Hello,

Is there a plan to bring wrappers around the sr_plugin_init_cb and sr_plugin_cleanup_cb ?

The way I'm handling a plugin right now is by initiating a new connection in the init callback and storing a shared_ptr to the Subscription class. Is there a better way of handling this, I was thinking by wrapping the raw session pointer given by the callback (maybe with wrapUnmanagedSession which is not exposed through the API) ?

Kind regards,
Paul.

utils compile error

_[ 38%] Built target sysrepo-cpp
[ 44%] Building CXX object CMakeFiles/DoctestIntegration.dir/tests/doctest-integration.cpp.o
[ 50%] Building CXX object CMakeFiles/DoctestIntegration.dir/tests/utils.cpp.o
/home/vmware/sysrepo-cpp-master/tests/utils.cpp:14:10: fatal error: trompeloeil.hpp: No such file or directory
14 | #include <trompeloeil.hpp>
| ^~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/DoctestIntegration.dir/tests/utils.cpp.o] Error 1
make[1]: *** [CMakeFiles/DoctestIntegration.dir/all] Error 2
make: *** [all] Error 2
_

Does it depend from https://github.com/rollbear/trompeloeil ? Should I install that one as well?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.