C++: use std::string instead of std::string_view

...in a lot of places which are related to libyang-cpp and sysrepo-cpp,
but also in some code that's velia-specific.

Change-Id: I9fc567480cb34131c790c74f75b7238cc00e0e84
Depends-on: https://gerrit.cesnet.cz/c/CzechLight/dependencies/+/7626
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ab624af..024ff64 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -44,8 +44,8 @@
 endif()
 #TODO: Check patch 20333 active
 
-pkg_check_modules(SYSREPO REQUIRED IMPORTED_TARGET sysrepo sysrepo-cpp>=2)
-pkg_check_modules(LIBYANG REQUIRED IMPORTED_TARGET libyang libyang-cpp>=2)
+pkg_check_modules(SYSREPO REQUIRED IMPORTED_TARGET sysrepo sysrepo-cpp>=3)
+pkg_check_modules(LIBYANG REQUIRED IMPORTED_TARGET libyang libyang-cpp>=3)
 pkg_check_modules(LIBNL REQUIRED IMPORTED_TARGET libnl-route-3.0)
 
 include(GNUInstallDirs)
diff --git a/src/firewall/Firewall.cpp b/src/firewall/Firewall.cpp
index a9352bd..f95ed39 100644
--- a/src/firewall/Firewall.cpp
+++ b/src/firewall/Firewall.cpp
@@ -25,7 +25,6 @@
 
 std::string generateNftConfig(velia::Log logger, const libyang::DataNode& tree, const std::vector<std::filesystem::path>& nftIncludes)
 {
-    using namespace std::string_view_literals;
     std::ostringstream ss;
     ss << "flush ruleset" << "\n";
     ss << "add table inet filter" << "\n";
@@ -35,22 +34,22 @@
 
     constexpr std::array skippedNodes{
         // Top-level container - don't care
-        "/ietf-access-control-list:acls"sv,
+        "/ietf-access-control-list:acls",
         // ACL container
-        "/ietf-access-control-list:acls/acl"sv,
+        "/ietf-access-control-list:acls/acl",
         // ACL name - don't care, we always only have one ACL
-        "/ietf-access-control-list:acls/acl/name"sv,
+        "/ietf-access-control-list:acls/acl/name",
         // ACEs container - don't care
-        "/ietf-access-control-list:acls/acl/aces"sv,
+        "/ietf-access-control-list:acls/acl/aces",
         // The type is either ipv4, ipv6, eth (which is disabled by a deviation) or a mix of these. The type is there
         // only for YANG validation and doesn't matter to us, because we check for "ipv4" and "ipv6" container.
-        "/ietf-access-control-list:acls/acl/type"sv,
+        "/ietf-access-control-list:acls/acl/type",
         // These are ignored, because they do not give any meaningful information. They are mostly containers.
-        "/ietf-access-control-list:acls/acl/aces/ace"sv,
-        "/ietf-access-control-list:acls/acl/aces/ace/matches"sv,
-        "/ietf-access-control-list:acls/acl/aces/ace/matches/ipv4"sv,
-        "/ietf-access-control-list:acls/acl/aces/ace/matches/ipv6"sv,
-        "/ietf-access-control-list:acls/acl/aces/ace/actions"sv,
+        "/ietf-access-control-list:acls/acl/aces/ace",
+        "/ietf-access-control-list:acls/acl/aces/ace/matches",
+        "/ietf-access-control-list:acls/acl/aces/ace/matches/ipv4",
+        "/ietf-access-control-list:acls/acl/aces/ace/matches/ipv6",
+        "/ietf-access-control-list:acls/acl/aces/ace/actions",
     };
 
     logger->trace("traversing the tree");
@@ -79,11 +78,11 @@
             // Action is the last statement we get, so this is where we create the actual rule.
             ss << "add rule inet filter acls" << match;
             auto action = velia::utils::getValueAsString(node);
-            if (action ==  "ietf-access-control-list:accept"sv) {
+            if (action == "ietf-access-control-list:accept") {
                 ss << " accept";
-            } else if (action ==  "ietf-access-control-list:drop"sv) {
+            } else if (action == "ietf-access-control-list:drop") {
                 ss << " drop";
-            } else if (action ==  "ietf-access-control-list:reject"sv) {
+            } else if (action == "ietf-access-control-list:reject") {
                 ss << " reject";
             } else {
                 // This should theoretically never happen.
diff --git a/src/health/outputs/AlarmsOutputs.cpp b/src/health/outputs/AlarmsOutputs.cpp
index 758511d..1cf826e 100644
--- a/src/health/outputs/AlarmsOutputs.cpp
+++ b/src/health/outputs/AlarmsOutputs.cpp
@@ -63,7 +63,7 @@
                         break;
                     }
 
-                    const auto activeAlarms = std::stoi(std::string(node->asTerm().valueStr()));
+                    const auto activeAlarms = std::stoi(node->asTerm().valueStr());
                     if (activeAlarms > 0) {
                         state = errorState;
                         break;
diff --git a/src/system/Firmware.cpp b/src/system/Firmware.cpp
index fa73455..4b5956c 100644
--- a/src/system/Firmware.cpp
+++ b/src/system/Firmware.cpp
@@ -7,6 +7,7 @@
 
 #include <regex>
 #include "Firmware.h"
+#include "utils/libyang.h"
 #include "utils/log.h"
 #include "utils/sysrepo.h"
 
@@ -81,7 +82,7 @@
         auto lock = updateSlotStatus();
 
         try {
-            auto source = std::string{input.findPath("url")->asTerm().valueStr()};
+            auto source = utils::getValueAsString(*input.findPath("url"));
             m_rauc->install(source);
         } catch (sdbus::Error& e) {
             m_log->warn("RAUC install error: '{}'", e.what());
@@ -94,7 +95,7 @@
     m_srSubscribeRPC = m_srSessionRPC.onRPCAction(CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/install", cbRPC);
 
     ::sysrepo::RpcActionCb markSlotAs = [this](auto, auto, auto path, auto input, auto, auto, auto) {
-        auto bootName = std::string{input.parent()->findPath("name")->asTerm().valueStr()};
+        auto bootName = utils::getValueAsString(*input.parent()->findPath("name"));
         std::string action;
         if (path == CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "firmware-slot/set-active-after-reboot") {
             action = "active";
diff --git a/src/system/JournalUpload.cpp b/src/system/JournalUpload.cpp
index c051d72..e3c20e9 100644
--- a/src/system/JournalUpload.cpp
+++ b/src/system/JournalUpload.cpp
@@ -10,6 +10,7 @@
 #include <sysrepo-cpp/Enum.hpp>
 #include "JournalUpload.h"
 #include "utils/io.h"
+#include "utils/libyang.h"
 #include "utils/log.h"
 
 using namespace std::string_literals;
@@ -28,7 +29,7 @@
     std::string url;
 
     auto hostNode = data->findPath(UPLOAD_URL_CONTAINER + "/host"s);
-    auto hostValue = std::string{hostNode->asTerm().valueStr()};
+    auto hostValue = velia::utils::getValueAsString(*hostNode);
     auto isIpv6 = hostNode->asTerm().valueType().internalPluginId().find("ipv6") != std::string::npos;
 
     url += data->findPath(UPLOAD_URL_CONTAINER + "/protocol"s)->asTerm().valueStr();
@@ -41,7 +42,7 @@
     }
 
     url += ":";
-    url += std::string(data->findPath(UPLOAD_URL_CONTAINER + "/port"s)->asTerm().valueStr());
+    url += data->findPath(UPLOAD_URL_CONTAINER + "/port"s)->asTerm().valueStr();
 
     return url;
 }
diff --git a/src/system/LLDPCallback.cpp b/src/system/LLDPCallback.cpp
index 5eb1f3d..ca579b4 100644
--- a/src/system/LLDPCallback.cpp
+++ b/src/system/LLDPCallback.cpp
@@ -17,7 +17,7 @@
 {
 }
 
-sysrepo::ErrorCode LLDPCallback::operator()(sysrepo::Session session, uint32_t, std::string_view, std::optional<std::string_view> subXPath, std::optional<std::string_view> requestXPath, uint32_t, std::optional<libyang::DataNode>& output)
+sysrepo::ErrorCode LLDPCallback::operator()(sysrepo::Session session, uint32_t, const std::string&, const std::optional<std::string>& subXPath, const std::optional<std::string>& requestXPath, uint32_t, std::optional<libyang::DataNode>& output)
 {
     m_log->trace("operational data callback: subXPath {} request-XPath {}",
             subXPath ? *subXPath : "(none)", requestXPath ? *requestXPath : "(none)");
diff --git a/src/system/LLDPCallback.h b/src/system/LLDPCallback.h
index 16f6dc3..69f2772 100644
--- a/src/system/LLDPCallback.h
+++ b/src/system/LLDPCallback.h
@@ -20,7 +20,7 @@
 class LLDPCallback {
 public:
     explicit LLDPCallback(std::shared_ptr<LLDPDataProvider> lldp);
-    sysrepo::ErrorCode operator()(sysrepo::Session session, uint32_t subscriptionId, std::string_view moduleName, std::optional<std::string_view> subXPath, std::optional<std::string_view> requestXPath, uint32_t, std::optional<libyang::DataNode>& output);
+    sysrepo::ErrorCode operator()(sysrepo::Session session, uint32_t subscriptionId, const std::string& moduleName, const std::optional<std::string>& subXPath, const std::optional<std::string>& requestXPath, uint32_t, std::optional<libyang::DataNode>& output);
 
 private:
     velia::Log m_log;
diff --git a/tests/sysrepo-helpers/common.cpp b/tests/sysrepo-helpers/common.cpp
index 0f266c5..e621d5c 100644
--- a/tests/sysrepo-helpers/common.cpp
+++ b/tests/sysrepo-helpers/common.cpp
@@ -64,7 +64,7 @@
 
     Values res;
     for (const auto& node : output.childrenDfs()) {
-        const auto briefXPath = std::string{node.path()}.substr(rpcPath.size());
+        const auto briefXPath = node.path().substr(rpcPath.size());
 
         // We ignore the thing that's exactly the xpath we're retrieving to avoid having {"": ""} entries.
         if (briefXPath.empty()) {
diff --git a/tests/sysrepo_ietf-hardware.cpp b/tests/sysrepo_ietf-hardware.cpp
index b03444a..003f593 100644
--- a/tests/sysrepo_ietf-hardware.cpp
+++ b/tests/sysrepo_ietf-hardware.cpp
@@ -10,6 +10,7 @@
 #include "sysrepo-helpers/datastore.h"
 #include "test_log_setup.h"
 #include "tests/sysrepo-helpers/common.h"
+#include "utils/libyang.h"
 
 using namespace std::literals;
 
@@ -45,7 +46,7 @@
     auto directLeafNodeQuery = [&](const std::string& xpath) {
         auto val = client.getData(xpath);
         REQUIRE(val);
-        return std::string{val->findPath(xpath)->asTerm().valueStr()};
+        return velia::utils::getValueAsString(*val->findPath(xpath));
     };
 
     auto sysfsTempCpu = std::make_shared<FakeHWMon>();