| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License |
| |
| #ifndef __PROCESS_HELP_HPP__ |
| #define __PROCESS_HELP_HPP__ |
| |
| #include <string> |
| |
| #include <process/future.hpp> |
| #include <process/http.hpp> |
| #include <process/process.hpp> |
| |
| #include <stout/foreach.hpp> |
| #include <stout/json.hpp> |
| #include <stout/option.hpp> |
| #include <stout/preprocessor.hpp> |
| #include <stout/stringify.hpp> |
| #include <stout/strings.hpp> |
| |
| namespace process { |
| |
| // Constructs a Markdown based help "page" for a route with the |
| // following template: |
| // |
| // ### USAGE ### |
| // usage |
| // |
| // ### TL;DR; ### |
| // tldr |
| // |
| // ### DESCRIPTION ### |
| // description |
| // |
| // ### AUTHENTICATION ### |
| // authentication requirements |
| // |
| // ### AUTHORIZATION ### |
| // authorization requirements and granularity |
| // |
| // references |
| // |
| // See the 'USAGE', 'TLDR', 'DESCRIPTION', 'AUTHENTICATION', and |
| // 'REFERENCES' helpers below to more easily construct your help pages. |
| std::string HELP( |
| const std::string& tldr, |
| const Option<std::string>& description = None(), |
| const Option<std::string>& authentication = None(), |
| const Option<std::string>& authorization = None(), |
| const Option<std::string>& references = None()); |
| |
| // Helper for single-line usage that puts it in a blockquote as code |
| // and adds a newline. |
| inline std::string USAGE(const std::string& usage) |
| { |
| return "> " + usage + "\n"; |
| } |
| |
| |
| // Helper for single-line TL;DR; that adds a newline. |
| inline std::string TLDR(const std::string& tldr) |
| { |
| return tldr + "\n"; |
| } |
| |
| |
| template <typename... T> |
| inline std::string DESCRIPTION(T&&... args) |
| { |
| return strings::join("\n", std::forward<T>(args)..., "\n"); |
| } |
| |
| |
| // Helper for description of Authentication requirements. |
| inline std::string AUTHENTICATION(bool required) |
| { |
| if (required) { |
| return "This endpoint requires authentication iff HTTP authentication is\n" |
| "enabled.\n"; |
| } |
| return "This endpoint does not require authentication.\n"; |
| } |
| |
| |
| // Helper for description of Authorization requirements. |
| template <typename... T> |
| inline std::string AUTHORIZATION(T&&... args) |
| { |
| return strings::join("\n", std::forward<T>(args)..., "\n"); |
| } |
| |
| |
| template <typename... T> |
| inline std::string REFERENCES(T&&... args) |
| { |
| return strings::join("\n", std::forward<T>(args)..., "\n"); |
| } |
| |
| |
| // Help process for serving /help, /help/id, and /help/id/name (see |
| // Help::help below for more information). |
| class Help : public Process<Help> |
| { |
| public: |
| Help(const Option<std::string>& delegate); |
| |
| // Adds 'help' for the route 'name' of the process with the |
| // specified 'id' (i.e., 'http://ip:port/id/name'). It's expected |
| // that 'help' is written using Markdown. When serving help to a |
| // browser the Markdown will be rendered into HTML while a tool like |
| // 'curl' or 'http' will just be given the Markdown directly (thus |
| // making it easy to get help without opening a browser). |
| // NOTE: There is no need to dispatch this directly; this gets |
| // automagically dispatched by 'ProcessBase::route'. |
| void add(const std::string& id, |
| const std::string& name, |
| const Option<std::string>& help); |
| |
| // Remove a previously installed 'help' string for '/id/name'. |
| bool remove(const std::string& id, const std::string& name); |
| |
| // Remove all previously installed 'help' strings for '/id/*'. |
| bool remove(const std::string& id); |
| |
| // Allow the global json function to dump this object to its |
| // canonical JSON representation. |
| friend void json(JSON::ObjectWriter* writer, const Help& help); |
| |
| protected: |
| void initialize() override; |
| |
| private: |
| // Handles the following: |
| // |
| // (1) http://ip:port/help |
| // (2) http://ip:port/help/id |
| // (3) http://ip:port/help/id/name |
| // |
| // Where 'id' and 'name' are replaced with a process ID and route |
| // name respectively. (1) provides a "table of contents" for all |
| // available processes while (2) provides a "table of contents" for |
| // all endpoints associated with a particular process and (3) |
| // provides the help associated with a particular endpoint of a |
| // process. |
| Future<http::Response> help(const http::Request& request); |
| |
| // Helper function to get usage path by process id and endpoint name. |
| std::string getUsagePath(const std::string& id, const std::string& name); |
| |
| // Delegate process name to receive root HTTP requests. |
| const Option<std::string> delegate; |
| |
| std::map<std::string, std::map<std::string, std::string>> helps; |
| }; |
| |
| } // namespace process { |
| |
| #endif // __PROCESS_HELP_HPP__ |