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 
28 using namespace fawkes;
29 
30 /** @class PluginRestApi "skiller-rest-api.h"
31  * REST API backend for plugins.
32  * @author Tim Niemueller
33  */
34 
35 /** Constructor. */
36 PluginRestApi::PluginRestApi() : Thread("PluginRestApi", Thread::OPMODE_WAITFORWAKEUP)
37 {
38 }
39 
40 /** Destructor. */
42 {
43 }
44 
45 void
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 
59 void
61 {
63  delete rest_api_;
64 }
65 
66 void
68 {
69 }
70 
72 PluginRestApi::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 
102 PluginRestApi::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.