Fawkes API Fawkes Development Version
plugin-rest-api.cpp
1
2/***************************************************************************
3 * plugin-rest-api.cpp - Plugin REST API
4 *
5 * Created: Tue Apr 10 17:10:43 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 "plugin-rest-api.h"
23
24#include "model/Plugin.h"
25
26#include <webview/rest_api_manager.h>
27
28using namespace fawkes;
29
30/** @class PluginRestApi "skiller-rest-api.h"
31 * REST API backend for plugins.
32 * @author Tim Niemueller
33 */
34
35/** Constructor. */
36PluginRestApi::PluginRestApi() : Thread("PluginRestApi", Thread::OPMODE_WAITFORWAKEUP)
37{
38}
39
40/** Destructor. */
42{
43}
44
45void
47{
48 rest_api_ = new WebviewRestApi("plugins", logger);
50 WebRequest::METHOD_GET, "/?", std::bind(&PluginRestApi::cb_list_plugins, this));
52 WebRequest::METHOD_PUT,
53 "/{name}",
54 std::bind(
55 &PluginRestApi::cb_set_plugin_state, this, std::placeholders::_1, std::placeholders::_2));
57}
58
59void
61{
63 delete rest_api_;
64}
65
66void
68{
69}
70
72PluginRestApi::cb_list_plugins()
73{
75
76 auto available_plugins = plugin_manager->get_available_plugins();
77 for (const auto &i : available_plugins) {
78 const std::string &name = i.first;
79 const std::string &description = i.second;
80 bool is_loaded = plugin_manager->is_loaded(name.c_str());
81 bool is_meta = plugin_manager->is_meta_plugin(name);
82 ::Plugin p;
83 p.set_kind("Plugin");
84 p.set_apiVersion(::Plugin::api_version());
85 p.set_name(name);
86 p.set_description(description);
87 p.set_is_meta(is_meta);
88 if (is_meta) {
89 auto plugin_list = plugin_manager->get_meta_plugin_children(name);
90 std::vector<std::string> v{std::make_move_iterator(std::begin(plugin_list)),
91 std::make_move_iterator(std::end(plugin_list))};
92 p.set_meta_children(std::move(v));
93 }
94 p.set_is_loaded(is_loaded);
95 rv.push_back(std::move(p));
96 }
97
98 return rv;
99}
100
102PluginRestApi::cb_set_plugin_state(PluginOpRequest &request, WebviewRestParams &params)
103{
104 std::string plugin = params.path_arg("name");
105
106 PluginOpResponse response;
107 response.set_kind("PluginOpResponse");
109 response.set_name(plugin);
110
111 auto des_state = request.desired_state();
112 if (!des_state) {
113 response.set_state("ERROR");
114 response.set_message("Request is missing required field 'desired_state'");
115 throw WebviewRestException(WebReply::HTTP_BAD_REQUEST,
116 response,
117 params.has_query_arg("pretty"));
118 }
119
120 if (*des_state == "LOADED") {
121 try {
122 plugin_manager->load(plugin);
123 response.set_state("LOADED");
124 return response;
125 } catch (Exception &e) {
126 logger->log_error(name(), e);
127 response.set_state("ERROR");
128 response.set_message(e.what_no_backtrace());
129 throw WebviewRestException(WebReply::HTTP_INTERNAL_SERVER_ERROR,
130 response,
131 params.has_query_arg("pretty"));
132 }
133 } else if (*des_state == "AVAILABLE" || *des_state == "UNLOADED") {
134 try {
135 plugin_manager->unload(plugin);
136 response.set_state(*des_state);
137 return response;
138 } catch (Exception &e) {
139 logger->log_error(name(), e);
140 response.set_state("ERROR");
141 response.set_message(e.what_no_backtrace());
142 throw WebviewRestException(WebReply::HTTP_INTERNAL_SERVER_ERROR,
143 response,
144 params.has_query_arg("pretty"));
145 }
146 } else {
147 response.set_state("ERROR");
148 response.set_message("Unknown state requested");
149 throw WebviewRestException(WebReply::HTTP_BAD_REQUEST,
150 response,
151 params.has_query_arg("pretty"));
152 }
153}
PluginOpRequest representation for JSON transfer.
std::optional< std::string > desired_state() const
Get desired_state value.
PluginOpResponse representation for JSON transfer.
static std::string api_version()
Get version of implemented API.
void set_message(const std::string &message)
Set message value.
void set_kind(const std::string &kind)
Set kind value.
void set_name(const std::string &name)
Set name value.
void set_state(const std::string &state)
Set state value.
void set_apiVersion(const std::string &apiVersion)
Set apiVersion value.
PluginRestApi()
Constructor.
virtual void loop()
Code to execute in the thread.
virtual void finalize()
Finalize the thread.
~PluginRestApi()
Destructor.
virtual void init()
Initialize the thread.
static std::string api_version()
Get version of implemented API.
Definition: Plugin.h:48
Container to return array via REST.
Definition: rest_array.h:36
void push_back(M &m)
Add item at the back of the container.
Definition: rest_array.h:123
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
Logger * logger
This is the Logger member used to access the logger.
Definition: logging.h:41
PluginManager * plugin_manager
This is the member used to access the PluginManager.
bool is_loaded(const std::string &plugin_name)
Check if plugin is loaded.
Definition: manager.cpp:257
void unload(const std::string &plugin_name)
Unload plugin.
Definition: manager.cpp:427
std::list< std::pair< std::string, std::string > > get_available_plugins()
Generate list of all available plugins.
Definition: manager.cpp:218
void load(const std::string &plugin_list)
Load plugin.
Definition: manager.cpp:325
std::list< std::string > get_meta_plugin_children(const std::string &plugin_name)
Get meta plugin children.
Definition: manager.cpp:287
bool is_meta_plugin(const std::string &plugin_name)
Check if plugin is a meta plugin.
Definition: manager.cpp:272
Plugin interface class.
Definition: plugin.h:34
void set_name(const char *name)
Set plugin name.
Definition: plugin.cpp:122
Thread class encapsulation of pthreads.
Definition: thread.h:46
const char * name() const
Get name of thread.
Definition: thread.h:100
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 processing exception.
Definition: rest_api.h:71
REST parameters to pass to handlers.
Definition: rest_api.h:125
bool has_query_arg(const std::string &what)
Check if query argument is set.
Definition: rest_api.h:174
std::string path_arg(const std::string &what)
Get a path argument.
Definition: rest_api.h:142
Fawkes library namespace.