blob: 113a923ffc1bf48c4ce03db6985425c4103cc6b2 [file] [log] [blame]
/*
* Copyright (C) 2020 CESNET, https://photonics.cesnet.cz/
*
* Written by Václav Kubernát <kubernat@cesnet.cz>
*
*/
#include <boost/algorithm/string/predicate.hpp>
#include "proxy_datastore.hpp"
#include "yang_schema.hpp"
ProxyDatastore::ProxyDatastore(const std::shared_ptr<DatastoreAccess>& datastore, std::function<std::shared_ptr<DatastoreAccess>(const std::shared_ptr<DatastoreAccess>&)> createTemporaryDatastore)
: m_datastore(datastore)
, m_createTemporaryDatastore(createTemporaryDatastore)
{
}
DatastoreAccess::Tree ProxyDatastore::getItems(const std::string& path) const
{
return pickDatastore(path)->getItems(path);
}
void ProxyDatastore::setLeaf(const std::string& path, leaf_data_ value)
{
pickDatastore(path)->setLeaf(path, value);
}
void ProxyDatastore::createItem(const std::string& path)
{
pickDatastore(path)->createItem(path);
}
void ProxyDatastore::deleteItem(const std::string& path)
{
pickDatastore(path)->deleteItem(path);
}
void ProxyDatastore::moveItem(const std::string& source, std::variant<yang::move::Absolute, yang::move::Relative> move)
{
pickDatastore(source)->moveItem(source, move);
}
void ProxyDatastore::commitChanges()
{
m_datastore->commitChanges();
}
void ProxyDatastore::discardChanges()
{
m_datastore->discardChanges();
}
void ProxyDatastore::copyConfig(const Datastore source, const Datastore destination)
{
m_datastore->copyConfig(source, destination);
}
std::string ProxyDatastore::dump(const DataFormat format) const
{
return m_datastore->dump(format);
}
namespace {
struct getInputPath {
template <typename InputType>
auto operator()(const InputType& input)
{
return input.m_path;
}
};
}
void ProxyDatastore::initiateRpc(const std::string& rpcPath)
{
if (m_inputDatastore) {
throw std::runtime_error("RPC/action input already in progress (" + std::visit(getInputPath{}, m_inputPath) + ")");
}
m_inputDatastore = m_createTemporaryDatastore(m_datastore);
m_inputPath = RpcInput{rpcPath};
m_inputDatastore->createItem(rpcPath);
}
void ProxyDatastore::initiateAction(const std::string& actionPath)
{
if (m_inputDatastore) {
throw std::runtime_error("RPC/action input already in progress (" + std::visit(getInputPath{}, m_inputPath) + ")");
}
m_inputDatastore = m_createTemporaryDatastore(m_datastore);
m_inputPath = ActionInput{actionPath};
m_inputDatastore->createItem(actionPath);
}
DatastoreAccess::Tree ProxyDatastore::execute()
{
if (!m_inputDatastore) {
throw std::runtime_error("No RPC/action input in progress");
}
auto inputData = m_inputDatastore->getItems("/");
m_inputDatastore = nullptr;
if (std::holds_alternative<RpcInput>(m_inputPath)) {
return m_datastore->executeRpc(std::visit(getInputPath{}, m_inputPath), inputData);
} else {
return m_datastore->executeAction(std::visit(getInputPath{}, m_inputPath), inputData);
}
}
void ProxyDatastore::cancel()
{
m_inputDatastore = nullptr;
}
std::shared_ptr<Schema> ProxyDatastore::schema() const
{
return m_datastore->schema();
}
std::shared_ptr<DatastoreAccess> ProxyDatastore::pickDatastore(const std::string& path) const
{
if (!m_inputDatastore || !boost::starts_with(path, std::visit(getInputPath{}, m_inputPath))) {
return m_datastore;
} else {
return m_inputDatastore;
}
}