blob: 393edef7cb4f66ae7a63f43a2ecb50bf305fe59d [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 {
63struct getInputPath
64{
65 template<typename InputType>
66 auto operator()(const InputType& input)
67 {
68 return input.m_path;
69 }
70};
71}
72
Václav Kubernáte7248b22020-06-26 15:38:59 +020073void ProxyDatastore::initiateRpc(const std::string& rpcPath)
74{
75 if (m_inputDatastore) {
Václav Kubernátaa4250a2020-07-22 00:02:23 +020076 throw std::runtime_error("RPC/action input already in progress (" + std::visit(getInputPath{}, m_inputPath) + ")");
Václav Kubernáte7248b22020-06-26 15:38:59 +020077 }
78 m_inputDatastore = m_createTemporaryDatastore(m_datastore);
Václav Kubernátaa4250a2020-07-22 00:02:23 +020079 m_inputPath = RpcInput{rpcPath};
Václav Kubernáte7248b22020-06-26 15:38:59 +020080 m_inputDatastore->createItem(rpcPath);
81}
82
Václav Kubernátaa4250a2020-07-22 00:02:23 +020083void ProxyDatastore::initiateAction(const std::string& actionPath)
84{
85 if (m_inputDatastore) {
86 throw std::runtime_error("RPC/action input already in progress (" + std::visit(getInputPath{}, m_inputPath) + ")");
87 }
88 m_inputDatastore = m_createTemporaryDatastore(m_datastore);
89 m_inputPath = ActionInput{actionPath};
90 m_inputDatastore->createItem(actionPath);
91}
92
93DatastoreAccess::Tree ProxyDatastore::execute()
Václav Kubernáte7248b22020-06-26 15:38:59 +020094{
95 if (!m_inputDatastore) {
Václav Kubernátaa4250a2020-07-22 00:02:23 +020096 throw std::runtime_error("No RPC/action input in progress");
Václav Kubernáte7248b22020-06-26 15:38:59 +020097 }
98 auto inputData = m_inputDatastore->getItems("/");
99 m_inputDatastore = nullptr;
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200100 if (std::holds_alternative<RpcInput>(m_inputPath)) {
101 return m_datastore->executeRpc(std::visit(getInputPath{}, m_inputPath), inputData);
102 } else {
103 return m_datastore->executeAction(std::visit(getInputPath{}, m_inputPath), inputData);
104 }
Václav Kubernáte7248b22020-06-26 15:38:59 +0200105}
106
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200107void ProxyDatastore::cancel()
Václav Kubernáte7248b22020-06-26 15:38:59 +0200108{
109 m_inputDatastore = nullptr;
110}
111
Václav Kubernát48e9dfa2020-07-08 10:55:12 +0200112std::shared_ptr<Schema> ProxyDatastore::schema() const
113{
114 return m_datastore->schema();
115}
Václav Kubernáte7248b22020-06-26 15:38:59 +0200116
117std::shared_ptr<DatastoreAccess> ProxyDatastore::pickDatastore(const std::string& path) const
118{
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200119 if (!m_inputDatastore || !boost::starts_with(path, std::visit(getInputPath{}, m_inputPath))) {
Václav Kubernáte7248b22020-06-26 15:38:59 +0200120 return m_datastore;
121 } else {
122 return m_inputDatastore;
123 }
124}