blob: 113a923ffc1bf48c4ce03db6985425c4103cc6b2 [file] [log] [blame]
Václav Kubernát48e9dfa2020-07-08 10:55:12 +02001/*
2 * Copyright (C) 2020 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Václav Kubernát <kubernat@cesnet.cz>
5 *
6*/
Václav Kubernáte7248b22020-06-26 15:38:59 +02007#include <boost/algorithm/string/predicate.hpp>
Václav Kubernát48e9dfa2020-07-08 10:55:12 +02008#include "proxy_datastore.hpp"
Václav Kubernáte7248b22020-06-26 15:38:59 +02009#include "yang_schema.hpp"
Václav Kubernát48e9dfa2020-07-08 10:55:12 +020010
Václav Kubernáte7248b22020-06-26 15:38:59 +020011ProxyDatastore::ProxyDatastore(const std::shared_ptr<DatastoreAccess>& datastore, std::function<std::shared_ptr<DatastoreAccess>(const std::shared_ptr<DatastoreAccess>&)> createTemporaryDatastore)
Václav Kubernát48e9dfa2020-07-08 10:55:12 +020012 : m_datastore(datastore)
Václav Kubernáte7248b22020-06-26 15:38:59 +020013 , m_createTemporaryDatastore(createTemporaryDatastore)
Václav Kubernát48e9dfa2020-07-08 10:55:12 +020014{
15}
16
17DatastoreAccess::Tree ProxyDatastore::getItems(const std::string& path) const
18{
Václav Kubernáte7248b22020-06-26 15:38:59 +020019 return pickDatastore(path)->getItems(path);
Václav Kubernát48e9dfa2020-07-08 10:55:12 +020020}
21
22void ProxyDatastore::setLeaf(const std::string& path, leaf_data_ value)
23{
Václav Kubernáte7248b22020-06-26 15:38:59 +020024 pickDatastore(path)->setLeaf(path, value);
Václav Kubernát48e9dfa2020-07-08 10:55:12 +020025}
26
27void ProxyDatastore::createItem(const std::string& path)
28{
Václav Kubernáte7248b22020-06-26 15:38:59 +020029 pickDatastore(path)->createItem(path);
Václav Kubernát48e9dfa2020-07-08 10:55:12 +020030}
31
32void ProxyDatastore::deleteItem(const std::string& path)
33{
Václav Kubernáte7248b22020-06-26 15:38:59 +020034 pickDatastore(path)->deleteItem(path);
Václav Kubernát48e9dfa2020-07-08 10:55:12 +020035}
36
37void ProxyDatastore::moveItem(const std::string& source, std::variant<yang::move::Absolute, yang::move::Relative> move)
38{
Václav Kubernáte7248b22020-06-26 15:38:59 +020039 pickDatastore(source)->moveItem(source, move);
Václav Kubernát48e9dfa2020-07-08 10:55:12 +020040}
41
42void ProxyDatastore::commitChanges()
43{
44 m_datastore->commitChanges();
45}
46
47void ProxyDatastore::discardChanges()
48{
49 m_datastore->discardChanges();
50}
51
52void ProxyDatastore::copyConfig(const Datastore source, const Datastore destination)
53{
54 m_datastore->copyConfig(source, destination);
55}
56
57std::string ProxyDatastore::dump(const DataFormat format) const
58{
59 return m_datastore->dump(format);
60}
61
Václav Kubernátaa4250a2020-07-22 00:02:23 +020062namespace {
Václav Kubernátb4e5b182020-11-16 19:55:09 +010063struct getInputPath {
64 template <typename InputType>
Václav Kubernátaa4250a2020-07-22 00:02:23 +020065 auto operator()(const InputType& input)
66 {
67 return input.m_path;
68 }
69};
70}
71
Václav Kubernáte7248b22020-06-26 15:38:59 +020072void ProxyDatastore::initiateRpc(const std::string& rpcPath)
73{
74 if (m_inputDatastore) {
Václav Kubernátaa4250a2020-07-22 00:02:23 +020075 throw std::runtime_error("RPC/action input already in progress (" + std::visit(getInputPath{}, m_inputPath) + ")");
Václav Kubernáte7248b22020-06-26 15:38:59 +020076 }
77 m_inputDatastore = m_createTemporaryDatastore(m_datastore);
Václav Kubernátaa4250a2020-07-22 00:02:23 +020078 m_inputPath = RpcInput{rpcPath};
Václav Kubernáte7248b22020-06-26 15:38:59 +020079 m_inputDatastore->createItem(rpcPath);
80}
81
Václav Kubernátaa4250a2020-07-22 00:02:23 +020082void ProxyDatastore::initiateAction(const std::string& actionPath)
83{
84 if (m_inputDatastore) {
85 throw std::runtime_error("RPC/action input already in progress (" + std::visit(getInputPath{}, m_inputPath) + ")");
86 }
87 m_inputDatastore = m_createTemporaryDatastore(m_datastore);
88 m_inputPath = ActionInput{actionPath};
89 m_inputDatastore->createItem(actionPath);
90}
91
92DatastoreAccess::Tree ProxyDatastore::execute()
Václav Kubernáte7248b22020-06-26 15:38:59 +020093{
94 if (!m_inputDatastore) {
Václav Kubernátaa4250a2020-07-22 00:02:23 +020095 throw std::runtime_error("No RPC/action input in progress");
Václav Kubernáte7248b22020-06-26 15:38:59 +020096 }
97 auto inputData = m_inputDatastore->getItems("/");
98 m_inputDatastore = nullptr;
Václav Kubernátaa4250a2020-07-22 00:02:23 +020099 if (std::holds_alternative<RpcInput>(m_inputPath)) {
100 return m_datastore->executeRpc(std::visit(getInputPath{}, m_inputPath), inputData);
101 } else {
102 return m_datastore->executeAction(std::visit(getInputPath{}, m_inputPath), inputData);
103 }
Václav Kubernáte7248b22020-06-26 15:38:59 +0200104}
105
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200106void ProxyDatastore::cancel()
Václav Kubernáte7248b22020-06-26 15:38:59 +0200107{
108 m_inputDatastore = nullptr;
109}
110
Václav Kubernát48e9dfa2020-07-08 10:55:12 +0200111std::shared_ptr<Schema> ProxyDatastore::schema() const
112{
113 return m_datastore->schema();
114}
Václav Kubernáte7248b22020-06-26 15:38:59 +0200115
116std::shared_ptr<DatastoreAccess> ProxyDatastore::pickDatastore(const std::string& path) const
117{
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200118 if (!m_inputDatastore || !boost::starts_with(path, std::visit(getInputPath{}, m_inputPath))) {
Václav Kubernáte7248b22020-06-26 15:38:59 +0200119 return m_datastore;
120 } else {
121 return m_inputDatastore;
122 }
123}