Fawkes API Fawkes Development Version
config-rest-api.cpp
1
2/***************************************************************************
3 * config-rest-api.cpp - Configuration REST API
4 *
5 * Created: Thu Apr 12 19:00:59 2018
6 * Copyright 2006-2018 Tim Niemueller [www.niemueller.de]
7 ****************************************************************************/
8
9/* This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
18 *
19 * Read the full text in the LICENSE.GPL file in the doc directory.
20 */
21
22#include "config-rest-api.h"
23
24#include <config/config.h>
25#include <rapidjson/document.h>
26#include <rapidjson/pointer.h>
27#include <webview/rest_api_manager.h>
28
29#include <memory>
30
31using namespace fawkes;
32
33/** @class ConfigurationRestApi "skiller-rest-api.h"
34 * REST API backend for plugins.
35 * @author Tim Niemueller
36 */
37
38/** Constructor. */
40: Thread("ConfigurationRestApi", Thread::OPMODE_WAITFORWAKEUP)
41{
42}
43
44/** Destructor. */
46{
47}
48
49void
51{
52 rest_api_ = new WebviewRestApi("config", logger);
53 rest_api_->add_handler<ConfigTree>(WebRequest::METHOD_GET,
54 "/?",
55 std::bind(&ConfigurationRestApi::cb_get_config,
56 this,
57 std::placeholders::_1));
59}
60
61void
63{
65 delete rest_api_;
66}
67
68void
70{
71}
72
73static rapidjson::Value
74create_value(std::unique_ptr<fawkes::Configuration::ValueIterator> &i,
75 rapidjson::Document::AllocatorType & a)
76{
77 rapidjson::Value v;
78 if (i->is_list()) {
79 v.SetArray();
80 v.Reserve(i->get_list_size(), a);
81 if (i->is_float()) {
82 std::vector<float> ivs = i->get_floats();
83 for (const auto &ivsv : ivs) {
84 v.PushBack(rapidjson::Value(ivsv).Move(), a);
85 }
86 } else if (i->is_uint()) {
87 std::vector<unsigned int> ivs = i->get_uints();
88 for (const auto &ivsv : ivs) {
89 v.PushBack(rapidjson::Value(ivsv).Move(), a);
90 }
91 } else if (i->is_int()) {
92 std::vector<int> ivs = i->get_ints();
93 for (const auto &ivsv : ivs) {
94 v.PushBack(rapidjson::Value(ivsv).Move(), a);
95 }
96 } else if (i->is_bool()) {
97 std::vector<bool> ivs = i->get_bools();
98 for (const auto &ivsv : ivs) {
99 v.PushBack(rapidjson::Value(ivsv).Move(), a);
100 }
101 } else if (i->is_string()) {
102 std::vector<std::string> ivs = i->get_strings();
103 for (const auto &ivsv : ivs) {
104 v.PushBack(rapidjson::Value(ivsv, a).Move(), a);
105 }
106 }
107 } else {
108 if (i->is_float()) {
109 v.SetFloat(i->get_float());
110 } else if (i->is_uint()) {
111 v.SetUint(i->get_uint());
112 } else if (i->is_int()) {
113 v.SetInt(i->get_int());
114 } else if (i->is_bool()) {
115 v.SetBool(i->get_bool());
116 } else if (i->is_string()) {
117 v.SetString(i->get_string(), a);
118 }
119 }
120 return v;
121}
122
124ConfigurationRestApi::cb_get_config(WebviewRestParams &params)
125{
126 std::string query{params.query_arg("query")};
127
128 ConfigTree response;
129 response.set_kind("ConfigTree");
131
132 std::shared_ptr<rapidjson::Document> d = std::make_shared<rapidjson::Document>();
133 rapidjson::Document::AllocatorType & a = d->GetAllocator();
134 d->SetObject();
135
136 //rapidjson::Value &v{*d};
137 std::unique_ptr<fawkes::Configuration::ValueIterator> i{config->search(query.c_str())};
138 while (i->next()) {
139 std::vector<std::string> path_elements{str_split(i->path(), '/')};
140 rapidjson::Value::MemberIterator parent = d->MemberEnd();
141 ;
142 rapidjson::Value::MemberIterator m = d->MemberBegin();
143 rapidjson::Value::MemberIterator m_end = d->MemberEnd();
144
145 if (path_elements.size() > 1) {
146 for (size_t p = 0; p < path_elements.size() - 1; ++p) {
147 m = std::find_if(m, m_end, [&path_elements, &p](const auto &v) {
148 return path_elements[p] == v.name.GetString();
149 });
150 if (m != m_end) {
151 parent = m;
152 } else {
153 if (parent != d->MemberEnd()) {
154 parent->value.AddMember(rapidjson::Value(path_elements[p], a).Move(),
155 rapidjson::Value(rapidjson::kObjectType).Move(),
156 a);
157 parent = parent->value.FindMember(path_elements[p].c_str());
158 } else {
159 d->AddMember(rapidjson::Value(path_elements[p], a).Move(),
160 rapidjson::Value(rapidjson::kObjectType).Move(),
161 a);
162 parent = d->FindMember(path_elements[p].c_str());
163 }
164 }
165 m = parent->value.MemberBegin();
166 m_end = parent->value.MemberEnd();
167 }
168
169 if (parent == d->MemberEnd()) {
170 d->AddMember(rapidjson::Value(path_elements.back(), a).Move(),
171 create_value(i, a).Move(),
172 a);
173 } else {
174 parent->value.AddMember(rapidjson::Value(path_elements.back(), a).Move(),
175 create_value(i, a).Move(),
176 a);
177 }
178 }
179 }
180 response.set_config(d);
181
182 return response;
183}
ConfigTree representation for JSON transfer.
Definition: ConfigTree.h:28
static std::string api_version()
Get version of implemented API.
Definition: ConfigTree.h:45
void set_apiVersion(const std::string &apiVersion)
Set apiVersion value.
Definition: ConfigTree.h:115
void set_kind(const std::string &kind)
Set kind value.
Definition: ConfigTree.h:98
void set_config(const std::shared_ptr< rapidjson::Document > &config)
Set config value.
Definition: ConfigTree.h:132
ConfigurationRestApi()
Constructor.
~ConfigurationRestApi()
Destructor.
virtual void init()
Initialize the thread.
virtual void finalize()
Finalize the thread.
virtual void loop()
Code to execute in the thread.
Configuration * config
This is the Configuration member used to access the configuration.
Definition: configurable.h:41
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
Logger * logger
This is the Logger member used to access the logger.
Definition: logging.h:41
Thread class encapsulation of pthreads.
Definition: thread.h:46
WebviewRestApiManager * webview_rest_api_manager
Webview REST API manager.
Definition: webview.h:55
void unregister_api(WebviewRestApi *api)
Remove a request processor.
void register_api(WebviewRestApi *api)
Add a REST API.
Webview REST API component.
Definition: rest_api.h:221
void add_handler(WebRequest::Method method, std::string path, Handler handler)
Add handler function.
Definition: rest_api.cpp:85
REST parameters to pass to handlers.
Definition: rest_api.h:125
std::string query_arg(const std::string &what)
Get a query argument.
Definition: rest_api.h:158
Fawkes library namespace.