blob: dc97c5233cdb5a76ad2c4ef6668f9874233946a5 [file] [log] [blame]
Tomáš Peckaba2dc312021-01-23 22:29:11 +01001/*
2 * Copyright (C) 2016-2021 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Jan Kundrát <jan.kundrat@cesnet.cz>
5 * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
6 *
7 */
8
9#include "sysrepo.h"
10#include "utils/log.h"
11
12extern "C" {
13#include <sysrepo.h>
14}
15
16extern "C" {
17/** @short Propagate sysrepo events to spdlog */
18static void spdlog_sr_log_cb(sr_log_level_t level, const char* message)
19{
20 // Thread safety note: this is, as far as I know, thread safe:
21 // - the static initialization itself is OK
22 // - all loggers which we instantiate are thread-safe
23 // - std::shared_ptr::operator-> is const, and all const members of that class are documented to be thread-safe
24 static auto log = spdlog::get("sysrepo");
25 assert(log);
26 switch (level) {
27 case SR_LL_NONE:
28 case SR_LL_ERR:
29 log->error(message);
30 break;
31 case SR_LL_WRN:
32 log->warn(message);
33 break;
34 case SR_LL_INF:
35 log->info(message);
36 break;
37 case SR_LL_DBG:
38 log->debug(message);
39 break;
40 }
41}
42}
43
44namespace velia::utils {
45
46/** @short Setup sysrepo log forwarding
47You must call cla::utils::initLogs prior to this function.
48*/
49void initLogsSysrepo()
50{
51 sr_log_set_cb(spdlog_sr_log_cb);
52}
53
54void valuesToYang(const std::map<std::string, std::string>& values, std::shared_ptr<::sysrepo::Session> session, std::shared_ptr<libyang::Data_Node>& parent)
55{
56 for (const auto& [propertyName, value] : values) {
57 spdlog::get("main")->trace("propertyName: {}, value: {}", propertyName, value.c_str());
58
59 if (!parent) {
60 parent = std::make_shared<libyang::Data_Node>(
61 session->get_context(),
62 propertyName.c_str(),
63 value.c_str(),
64 LYD_ANYDATA_CONSTSTRING,
65 LYD_PATH_OPT_OUTPUT);
66 } else {
67 parent->new_path(
68 session->get_context(),
69 propertyName.c_str(),
70 value.c_str(),
71 LYD_ANYDATA_CONSTSTRING,
72 LYD_PATH_OPT_OUTPUT);
73 }
74 }
75}
76
Tomáš Pecka272abaf2021-01-24 12:28:43 +010077/** @brief Set values into Sysrepo's specified datastore. It changes the datastore and after the data are applied, the original datastore is restored. */
78void valuesPush(const std::map<std::string, std::string>& values, std::shared_ptr<::sysrepo::Session> session, sr_datastore_t datastore)
79{
80 sr_datastore_t oldDatastore = session->session_get_ds();
81 session->session_switch_ds(datastore);
82
83 valuesPush(values, session);
84
85 session->apply_changes();
86 session->session_switch_ds(oldDatastore);
87}
88
89/** @brief Set values into Sysrepo's current datastore. */
90void valuesPush(const std::map<std::string, std::string>& values, std::shared_ptr<::sysrepo::Session> session)
91{
92 libyang::S_Data_Node edit;
93 valuesToYang(values, session, edit);
94
95 session->edit_batch(edit, "merge");
96 session->apply_changes();
97}
98
Václav Kubernát6fa7f342021-01-26 17:00:01 +010099/** @brief Checks whether a module is implemented in Sysrepo and throws if not. */
100void ensureModuleImplemented(std::shared_ptr<::sysrepo::Session> session, const std::string& module, const std::string& revision)
101{
102 if (auto mod = session->get_context()->get_module(module.c_str(), revision.c_str()); !mod || !mod->implemented()) {
103 throw std::runtime_error(module + "@" + revision + " is not implemented in sysrepo.");
104 }
105}
Tomáš Peckaba2dc312021-01-23 22:29:11 +0100106}