blob: d80f5399ddb1101dd86586c87950b2012d7b27cc [file] [log] [blame]
Václav Kubernát80aacc02018-08-22 17:41:54 +02001/*
2 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
3 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
4 *
5 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
6 *
7*/
8
9#include <sysrepo-cpp/Session.h>
10#include "sysrepo_access.hpp"
Václav Kubernáta6c5fff2018-09-07 15:16:25 +020011#include "yang_schema.hpp"
Václav Kubernát80aacc02018-08-22 17:41:54 +020012
Václav Kubernátc89736b2018-08-30 16:14:05 +020013leaf_data_ leafValueFromVal(const S_Val& value)
14{
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020015 using namespace std::string_literals;
Václav Kubernátc89736b2018-08-30 16:14:05 +020016 switch (value->type()) {
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020017 case SR_INT32_T:
18 return value->data()->get_int32();
19 case SR_UINT32_T:
20 return value->data()->get_uint32();
21 case SR_BOOL_T:
22 return value->data()->get_bool();
23 case SR_STRING_T:
24 return std::string(value->data()->get_string());
25 case SR_ENUM_T:
26 return std::string(value->data()->get_enum());
27 case SR_DECIMAL64_T:
28 return value->data()->get_decimal64();
29 case SR_CONTAINER_T:
30 return "(container)"s;
31 case SR_CONTAINER_PRESENCE_T:
32 return "(presence container)"s;
33 case SR_LIST_T:
34 return "(list)"s;
35 default: // TODO: implement all types
36 return value->val_to_string();
Václav Kubernátc89736b2018-08-30 16:14:05 +020037 }
38}
Václav Kubernát80aacc02018-08-22 17:41:54 +020039
40struct valFromValue : boost::static_visitor<S_Val> {
41 S_Val operator()(const enum_& value) const
42 {
43 return std::make_shared<Val>(value.m_value.c_str(), SR_ENUM_T);
44 }
45
46 S_Val operator()(const std::string& value) const
47 {
48 return std::make_shared<Val>(value.c_str());
49 }
50
51 S_Val operator()(const uint32_t& value) const
52 {
53 return std::make_shared<Val>(value, SR_UINT32_T);
54 }
55
56 S_Val operator()(const int32_t& value) const
57 {
58 return std::make_shared<Val>(value, SR_INT32_T);
59 }
60
61 S_Val operator()(const bool& value) const
62 {
63 return std::make_shared<Val>(value, SR_BOOL_T);
64 }
65
66 S_Val operator()(const double& value) const
67 {
68 return std::make_shared<Val>(value);
69 }
70};
71
Václav Kubernát812ee282018-08-30 17:10:03 +020072SysrepoAccess::~SysrepoAccess() = default;
Václav Kubernát80aacc02018-08-22 17:41:54 +020073
74SysrepoAccess::SysrepoAccess(const std::string& appname)
75 : m_connection(new Connection(appname.c_str()))
Václav Kubernáta6c5fff2018-09-07 15:16:25 +020076 , m_schema(new YangSchema())
Václav Kubernát80aacc02018-08-22 17:41:54 +020077{
78 m_session = std::make_shared<Session>(m_connection);
Václav Kubernáta6c5fff2018-09-07 15:16:25 +020079 m_schema->registerModuleCallback([this](const char* moduleName, const char* revision, const char* submodule) {
80 return fetchSchema(moduleName, revision, submodule);
81 });
82
83 for (const auto& it : listImplementedSchemas()) {
84 m_schema->loadModule(it);
85 }
Václav Kubernát80aacc02018-08-22 17:41:54 +020086}
87
88std::map<std::string, leaf_data_> SysrepoAccess::getItems(const std::string& path)
89{
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020090 using namespace std::string_literals;
Václav Kubernát80aacc02018-08-22 17:41:54 +020091 std::map<std::string, leaf_data_> res;
Václav Kubernát80aacc02018-08-22 17:41:54 +020092
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020093 auto fillMap = [&res](auto items) {
94 if (!items)
95 return;
96 for (unsigned int i = 0; i < items->val_cnt(); i++) {
97 res.emplace(items->val(i)->xpath(), leafValueFromVal(items->val(i)));
98 }
99 };
Václav Kubernátc89736b2018-08-30 16:14:05 +0200100
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200101 if (path == "/") {
102 // Sysrepo doesn't have a root node ("/"), so we take all top-level nodes from all schemas
103 auto schemas = m_session->list_schemas();
104 for (unsigned int i = 0; i < schemas->schema_cnt(); i++) {
105 fillMap(m_session->get_items(("/"s + schemas->schema(i)->module_name() + ":*//.").c_str()));
106 }
107 } else {
108 fillMap(m_session->get_items((path + "//.").c_str()));
Václav Kubernátc89736b2018-08-30 16:14:05 +0200109 }
Václav Kubernát80aacc02018-08-22 17:41:54 +0200110
111 return res;
112}
113
114void SysrepoAccess::setLeaf(const std::string& path, leaf_data_ value)
115{
116 m_session->set_item(path.c_str(), boost::apply_visitor(valFromValue(), value));
117}
118
119void SysrepoAccess::createPresenceContainer(const std::string& path)
120{
121 m_session->set_item(path.c_str());
122}
123
124void SysrepoAccess::deletePresenceContainer(const std::string& path)
125{
126 m_session->delete_item(path.c_str());
127}
Václav Kubernát812ee282018-08-30 17:10:03 +0200128
129void SysrepoAccess::commitChanges()
130{
131 m_session->commit();
132}
Václav Kubernáta6c5fff2018-09-07 15:16:25 +0200133
134std::string SysrepoAccess::fetchSchema(const char* module, const char* revision, const char* submodule)
135{
136 auto schema = m_session->get_schema(module, revision, submodule, SR_SCHEMA_YANG); // FIXME: maybe we should use get_submodule_schema for submodules?
137 if (schema.empty())
138 throw std::runtime_error(std::string("Module ") + module + " not available");
139
140 return schema;
141}
142
143std::vector<std::string> SysrepoAccess::listImplementedSchemas()
144{
145 std::vector<std::string> res;
146 auto schemas = m_session->list_schemas();
147 for (unsigned int i = 0; i < schemas->schema_cnt(); i++) {
148 auto schema = schemas->schema(i);
149 if (schema->implemented())
150 res.push_back(schema->module_name());
151 }
152 return res;
153}
154
155std::shared_ptr<Schema> SysrepoAccess::schema()
156{
157 return m_schema;
158}