From ee53d86929296c4824e9860f6425850f7d795302 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <tomas.pecka@cesnet.cz>
Date: Tue, 15 Apr 2025 11:06:50 +0200
Subject: [PATCH 19/20] add a session getter to dynamic subscriptions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires

Sometimes it might be useful to get the session which created the
subscription (e.g. to do some work in processEvent callback). There was
no easy way to do it up until now because the session was not stored as
sysrepo::Session.
However, it seems quite easy to change that and add the getter.

Change-Id: Ia943a47debba6f84c3faad5ea48a69da68dac874
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
 include/sysrepo-cpp/Subscription.hpp |  3 ++-
 src/Session.cpp                      |  6 +++---
 src/Subscription.cpp                 | 17 +++++++++++------
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/include/sysrepo-cpp/Subscription.hpp b/include/sysrepo-cpp/Subscription.hpp
index 7fdc08b..4c58e78 100644
--- a/include/sysrepo-cpp/Subscription.hpp
+++ b/include/sysrepo-cpp/Subscription.hpp
@@ -303,6 +303,7 @@ public:
     DynamicSubscription& operator=(DynamicSubscription&&) noexcept;
     ~DynamicSubscription();
 
+    sysrepo::Session getSession() const;
     int fd() const;
     uint64_t subscriptionId() const;
     std::optional<NotificationTimeStamp> replayStartTime() const;
@@ -310,7 +311,7 @@ public:
     void terminate(const std::optional<std::string>& reason = std::nullopt);
 
 private:
-    DynamicSubscription(std::shared_ptr<sr_session_ctx_s> sess, int fd, uint64_t subId, const std::optional<NotificationTimeStamp>& replayStartTime = std::nullopt);
+    DynamicSubscription(sysrepo::Session sess, int fd, uint64_t subId, const std::optional<NotificationTimeStamp>& replayStartTime = std::nullopt);
 
     struct Data;
     std::unique_ptr<Data> m_data;
diff --git a/src/Session.cpp b/src/Session.cpp
index 8258295..7d44662 100644
--- a/src/Session.cpp
+++ b/src/Session.cpp
@@ -588,7 +588,7 @@ DynamicSubscription Session::yangPushPeriodic(
                                        &subId);
     throwIfError(res, "Couldn't create yang-push periodic subscription", m_sess.get());
 
-    return {m_sess, fd, subId};
+    return {*this, fd, subId};
 }
 
 /**
@@ -637,7 +637,7 @@ DynamicSubscription Session::yangPushOnChange(
                                         &subId);
     throwIfError(res, "Couldn't create yang-push on-change subscription", m_sess.get());
 
-    return {m_sess, fd, subId};
+    return {*this, fd, subId};
 }
 
 /**
@@ -683,7 +683,7 @@ DynamicSubscription Session::subscribeNotifications(
         replayStart = toTimePoint(replayStartSpec);
     }
 
-    return {m_sess, fd, subId, replayStart};
+    return {*this, fd, subId, replayStart};
 }
 
 /**
diff --git a/src/Subscription.cpp b/src/Subscription.cpp
index ab27b16..6dccaee 100644
--- a/src/Subscription.cpp
+++ b/src/Subscription.cpp
@@ -414,18 +414,18 @@ bool ChangeIterator::operator==(const ChangeIterator& other) const
 
 
 struct DynamicSubscription::Data {
-    std::shared_ptr<sr_session_ctx_s> sess;
+    sysrepo::Session sess;
     int fd;
     uint64_t subId;
     std::optional<NotificationTimeStamp> m_replayStartTime;
     bool m_terminated;
 
-    Data(std::shared_ptr<sr_session_ctx_s> sess, int fd, uint64_t subId, const std::optional<NotificationTimeStamp>& replayStartTime, bool terminated);
+    Data(sysrepo::Session sess, int fd, uint64_t subId, const std::optional<NotificationTimeStamp>& replayStartTime, bool terminated);
     ~Data();
     void terminate(const std::optional<std::string>& reason = std::nullopt);
 };
 
-DynamicSubscription::DynamicSubscription(std::shared_ptr<sr_session_ctx_s> sess, int fd, uint64_t subId, const std::optional<NotificationTimeStamp>& replayStartTime)
+DynamicSubscription::DynamicSubscription(sysrepo::Session sess, int fd, uint64_t subId, const std::optional<NotificationTimeStamp>& replayStartTime)
     : m_data(std::make_unique<Data>(std::move(sess), fd, subId, replayStartTime, false))
 {
 }
@@ -434,6 +434,12 @@ DynamicSubscription::DynamicSubscription(DynamicSubscription&&) noexcept = defau
 DynamicSubscription& DynamicSubscription::operator=(DynamicSubscription&&) noexcept = default;
 DynamicSubscription::~DynamicSubscription() = default;
 
+/** @brief Returns sysrepo Session associated with this subscription */
+sysrepo::Session DynamicSubscription::getSession() const
+{
+    return m_data->sess;
+}
+
 /** @brief Returns the file descriptor associated with this subscription. */
 int DynamicSubscription::fd() const
 {
@@ -472,9 +478,8 @@ void DynamicSubscription::processEvent(YangPushNotifCb cb) const
 {
     struct timespec timestamp;
     struct lyd_node* tree;
-    auto ctx = std::unique_ptr<const ly_ctx, std::function<void(const ly_ctx*)>>(sr_session_acquire_context(m_data->sess.get()), [&](const ly_ctx*) { sr_session_release_context(m_data->sess.get()); });
 
-    auto err = srsn_read_notif(fd(), ctx.get(), &timestamp, &tree);
+    auto err = srsn_read_notif(fd(), libyang::retrieveContext(m_data->sess.getContext()), &timestamp, &tree);
     throwIfError(err, "Couldn't read yang-push notification");
 
     const auto wrappedNotification = tree ? std::optional{libyang::wrapRawNode(tree)} : std::nullopt;
@@ -488,7 +493,7 @@ void DynamicSubscription::processEvent(YangPushNotifCb cb) const
     cb(wrappedNotification, toTimePoint(timestamp));
 }
 
-DynamicSubscription::Data::Data(std::shared_ptr<sr_session_ctx_s> sess, int fd, uint64_t subId, const std::optional<NotificationTimeStamp>& replayStartTime, bool terminated)
+DynamicSubscription::Data::Data(sysrepo::Session sess, int fd, uint64_t subId, const std::optional<NotificationTimeStamp>& replayStartTime, bool terminated)
     : sess(std::move(sess))
     , fd(fd)
     , subId(subId)
-- 
2.43.0

